Search code examples
c#signalr

How do I read class name from config file in SignalR MapHub process


I'm doing message forwarding with SignalR. I want to read my multiple Hub classes from config file as my project will be huge. Below is an example MapHub operation, but I want to read the class name from the config.

    public static void Configure(IApplicationBuilder app)
    {
        IConfiguration config = app.ApplicationServices.GetService<IConfiguration>();
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<MyHub>("/myHub");// standart
            endpoints.MapHub<"will be read from config file" > (config.GetSection("Hubs").GetValue(typeof(string), "MyHub").ToString());  
        });
    }

Is there any way to do this? I would be glad if you help.


Solution

  • You have to use Reflection here as HubEndpointRouteBuilderExtensions class doesn't provide a none-generic version of MapHub method. Below code should work for your scenario.

    var extensionType = typeof(HubEndpointRouteBuilderExtensions);
    var mapHubMethod = extensionType.GetMethod("MapHub", BindingFlags.Public | BindingFlags.Static, new[] { typeof(IEndpointRouteBuilder), typeof(string) });
    var myHubTypeName = config.GetSection("Hubs").GetValue(typeof(string), "MyHub").ToString();
    // Assume it is something like this : 
    // "MyHubNameSpace.MyHub, MyAssembly, Version=1.2.3.0, Culture=neutral, PublicKeyToken=null"
    var myHubType = Type.GetType(myHubTypeName); // read from config
    var path = "foo"; // read from config
    var genericMapHub = mapHubMethod!.MakeGenericMethod(myHubType);
    
    app.UseEndpoints(endpoints =>
    {
        genericMapHub.Invoke(null, new object[] { endpoints, path });
    });
    

    If you have multiple Hubs in your config you need to have multiple genericMapHub method Infos :

    var genericMyHub = mapHubMethod.MakeGenericMethod(myHubType);
    var genericOtherHub = mapHubMethod.MakeGenericMethod(typeof(OtherHub));
    var genericAnother =  mapHubMethod.MakeGenericMethod(typeof(AnotherHub));
    // In practice this should be in a loop.