查找通用接口的实现

Find implementation of generic interface

我正在从程序集动态注册 classes,一堆命令处理程序:

class class DummyCommand : ICommand {}

class GetAgeCommandHandler : ICommandHandler<DummyCommand>
{
    public void Handle(DummyCommand command) { }
}

我的代码列出了实现通用接口的所有类型,在这种情况下,我对 ICommandHandler<> 具有以下辅助方法的接口感兴趣:

public static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(this Assembly assembly, Type openGenericType)
{
    return from x in assembly.GetTypes()
            from z in x.GetInterfaces()
            let y = x.BaseType
            where
            (y != null && y.IsGenericType &&
            openGenericType.IsAssignableFrom(y.GetGenericTypeDefinition())) ||
            (z.IsGenericType &&
            openGenericType.IsAssignableFrom(z.GetGenericTypeDefinition()))
            select x;
}

使用以下注册码:

var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var implementation in assembly.GetAllTypesImplementingOpenGenericType(typeof(ICommandHandler<>)))
{
    // below is wrong, i cannot get the generic type it is empty
    // var commandType = implementation.UnderlyingSystemType.GenericTypeArguments[0];
    // what should i put to find the type `DummyCommand`

    // registeration would be below
    var handlerType = (typeof(ICommandHandler<>)).MakeGenericType(commandType);
    container.Register(handlerType, implementation);
}

基本上我正在尝试向 SimpleInjector 容器(但可以是任何 ioc 容器)注册类型 container.Register(typeof(ICommandHandler<DummyCommand>), typeof(GetAgeCommandHandler)) 但是在运行时使用泛型,我还需要小心处理以下情况class 实现多个 ICommandHandler 接口(不同命令类型)。

不胜感激。

您可能有兴趣阅读 Simple Injector 的 fine manual on doing Auto-Registration,因为发布的代码块可以简化为简单的一行代码:

container.Register(typeof(ICommandHandler<>), AppDomain.CurrentDomain.GetAssemblies());