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