I'm trying to use LightInject and MediatR to build generic request handlers. Basically, I have types like the following:
public class SomeType { }
public class InheritedType : SomeType { }
public class Handler : IAsyncRequestHandler<SomeType, SomeResponseType> { }
And I have registered my Handler
type into my LightInject container like so:
registry.RegisterAssembly(typeof(SomeType).Assembly, (s, type) =>
!s.IsClass && type.IsAssignableToGenericType(typeof(IAsyncRequestHandler<,>)
);
However, when I try and call in to my mediator for an implementation of IAsyncRequestHandler<InheritedType,SomeResponseType>
, it fails. I would have expected to get my registered Handler
since InheritedType
implements SomeType
.
Am I doing something wrong here, or is there any way in LightInject to achieve the behaviour I've described above?
Let me know if it's not clear and I can try and provide more info. Thanks!
The Handler class closes both generic arguments and cannot be changed later. Just try manually to create a new instance of the Handler class and you will see that there is no way to specify the generic arguments because they are closed.
Change your code to this.
public class Handler<T, SomeResponseType> : IAsyncRequestHandler<T, SomeResponseType> where T:IAsyncRequest<SomeResponseType>
{
public Task<SomeResponseType> Handle(T message)
{
throw new NotImplementedException();
}
}
Register and resolve like this
var container = new ServiceContainer();
container.Register(typeof(IAsyncRequestHandler<,>), typeof(Handler<,>));
var instance = container.GetInstance<IAsyncRequestHandler<InheritedType, SomeResponseType>>();