I am registering classes dynamically from an assembly, a bunch of command handlers:
class class DummyCommand : ICommand {}
class GetAgeCommandHandler : ICommandHandler<DummyCommand>
{
public void Handle(DummyCommand command) { }
}
I have code which lists all types that implement the generic interface, in this case i am interested in ICommandHandler<>
interfaces with the below helper method:
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;
}
With the below registration code:
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);
}
Basically i am trying to register with the SimpleInjector
container (but could be any ioc container) the type container.Register(typeof(ICommandHandler<DummyCommand>), typeof(GetAgeCommandHandler))
but with generics at runtime, i need to also be careful to handle cases where a class implements multiple ICommandHandler
interfaces (of different command types).
Pointers much appreciated.