如何在C#中传递泛型函数中的类型

问题描述 投票:1回答:2

我有以下代码:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
    public class SignalRHub : Attribute
    {
        public readonly string Route;

        public SignalRHub(string Route)
        {
            this.Route = Route;
        }
    }

    [SignalRHub("hubpath")]
    public class TestHub : Hub
    {
        ...
    }

这定义了一个SignalR集线器,其中包含一个知道路径的属性。

我想动态地注册带有SignalRHub属性的集线器,所以我有以下代码来查找所有集线器:

        // find all hubs
        var Hubs =
            from Assemblies in AppDomain.CurrentDomain.GetAssemblies().AsParallel()
            from Types in Assemblies.GetTypes()
            let Attributes = Types.GetCustomAttributes(typeof(SignalRHub), true)
            where Attributes?.Length > 0
            select new { Type = Types };

        var HubsList = Hubs.ToList();

然后我想注册它们,但这是我遇到问题的地方:

        foreach (var H in HubsList)
        {
            // get the route attribute
            var Route = string.Empty;
            var Attributes = Attribute.GetCustomAttributes(H.Type);
            foreach (var Attribute in Attributes)
            {
                if (Attribute is SignalRHub A)
                {
                    Route = A.Route;
                    break;
                }
            }

            // register the hub
            if (string.IsNullOrEmpty(Route))
            {
                Logging.Warn($"[Hub] {H.Type.Name} does not have a path, skipping");
            }
            else
            {
                Logging.Info($"[Hub] Registering {H.Type.Name} with path {Route}");
                Application.UseSignalR(R => R.MapHub<H>(Route)); <- this won't compile
            }

MapHub要求T从Hub派生;如果H是TestHub类型,它应该没问题,但该语法不起作用。

我怎样才能做到这一点?

c# signalr
2个回答
1
投票

我的解决方案(使用反射)

using System;
using System.Reflection;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Connections;
//somewhere in your code
private static readonly MethodInfo mapperMethodInfo = 
    typeof(HubRouteBuilder).GetMethod(
        "MapHub",
        new Type [] { 
            typeof(PathString)
        },
        null
    );

// in your mapping code
// replace this:
Application.UseSignalR(R => R.MapHub<H>(Route));  

// with this
Application.UseSignalR(R => 
{
   // pay attention to use of H.Type, R and Route variables
   mapperMethodInfo.MakeGenericMethod(H.Type).Invoke(R, new object [] { Route });
});


0
投票

编译器不满意,因为您使用实例变量作为泛型类型。

因为H实例变量指向Hub实例,所以可以替换:

Application.UseSignalR(R => R.MapHub<H>(Route))

通过:

Application.UseSignalR(R => R.MapHub<Hub>(Route))
© www.soinside.com 2019 - 2024. All rights reserved.