Найти реализацию универсального интерфейса - PullRequest
0 голосов
/ 31 декабря 2018

Я регистрирую классы динамически из сборки, группы обработчиков команд:

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)), но с обобщениями во время выполнения, мне также нужно быть осторожным, чтобы обрабатывать случаи, когда класс реализует несколько ICommandHandler интерфейсов (разных типов команд).

Указатели очень ценятся.

1 Ответ

0 голосов
/ 31 декабря 2018

Возможно, вас заинтересует прочное руководство Simple Injector по автоматической регистрации , поскольку блок размещенного кода может быть уменьшен до простого однострочного:

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