在c#中从Generic接口查找已实现的类型

时间:2015-03-28 19:33:00

标签: c# generics reflection

public class AccountCreatedEvent : EventBase{}   

 public class AccountHandler : IEventHandler<AccountCreatedEvent>
    {
        public void Handle(AccountCreatedEvent event)
        {
        }
    }

这是一个处理程序类,我想用c#代码获取此类。我想从IEventHandler类型获取已实现类的列表。

public class Account
{
    public void OnAccountCreated(EventBase accountCreatedEvent)
    {            
        var handler = typeof(IEventHandler<>);            
        var events = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => handler .IsAssignableFrom(p) && handler.IsGenericType);

    }
}

但是var events正在返回

 {Name = "IEventHandler`1" FullName = "Project1.IEventHandler`1"}

2 个答案:

答案 0 :(得分:1)

正如Praveen所建议的,但是使用通用接口的处理方式

Type interfaceType = typeof(IEventHandler<>);
Assembly mscorlib = typeof(System.Int32).Assembly;
Assembly system = typeof(System.Uri).Assembly;
Assembly systemcore = typeof(System.Linq.Enumerable).Assembly;

var events = AppDomain.CurrentDomain.GetAssemblies()
    // We skip three common assemblies of Microsoft
    .Where(x => x != mscorlib && x != system && x != systemcore).ToArray();
    .SelectMany(s => s.GetTypes())
    .Where(p => p.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType)).ToArray();

请注意,为了加快这一点,我正在跳过三个常见的Microsoft程序集。跳过所有MS程序集有点复杂(可以通过PublicKeyToken完成,但我不认为这是一个非常好的想法...一个PublicKeyToken是64位,并不是真的保证是唯一的...并且检索程序集的完整PublicKey可能是一种痛苦)

答案 1 :(得分:-1)

以下代码将获取实现接口IEventHandler

的所有类型的列表
var events = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => p.GetInterfaces().Any(i => i.Name == handler.Name && i.Namespace == handler.Namespace));

我们基本上检查类实现的所有接口是否与处理程序接口名称匹配。您可以更加严格地检查命名空间等其他参数,以防您想要跨程序集进行搜索。