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

Viewed 101

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.

1 Answers

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.
Related