Search code examples
c#genericsmediatorlight-injectmediatr

LightInject doesn't resolve inherited generic types


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!


Solution

  • 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>>();