从 C# 中的通用接口中查找已实现的类型

Find implemented types from Generic interface in c#

public class AccountCreatedEvent : EventBase{}   

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

这是一个处理程序 class,我想用 C# 代码得到这个 class。我想从 IEventHandler 类型中获取已实现的 classes 列表。

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"}

下面的代码将获取实现 IEventHandler 接口的所有类型的列表

var events = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => p.GetInterfaces().Any(i => i.Name == handler.Name && i.Namespace == handler.Namespace));

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

如 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 可能很痛苦)