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