mardi 30 mai 2017

Microsoft Dependency Injection resolving generic type returns null

I am trying to translate something I used to do in Autofac to Microsoft Dependency Injection. I have a bunch of RequestHandlers that are based on an interface:

public interface IRequestHandler<TParameter, TResult>
    where TResult : IResponse
    where TParameter : IRequest
{
    TResult Handle(TParameter query);
}

I have registered all request handlers and all my IResponse objects and my IRequest objects by doing this:

 var requestHandlerAsyncs = ReflectionUtils.GetClosedTypes(typeof(IRequestHandlerAsync<,>), assemblies);
        foreach (var requestHandler in requestHandlerAsyncs)
        {
            serviceCollection.AddScoped(requestHandler);
        }

Im collecting all my types to be registered like this:

 public static IEnumerable<Type> GetClosedTypes(Type openGeneric, params Assembly[] assemblies)
    {
        if (assemblies == null || assemblies.Length == 0)
        {
            return new Type[0];
        }

        var list = new List<Type>();
        foreach (var assembly in assemblies)
        {
            if (!assembly.IsDynamic)
            {
                var types = ReflectionUtils.GetExportedTypes(assembly);

                var q = from type in types
                        from i in type.GetInterfaces()
                        where i.IsGenericType && i.GetGenericTypeDefinition() == openGeneric
                        select type;

                list.AddRange(q);
            }
        }

        return list;
    }

I can step through code and see that they are registered. I would then like to be able to retrieve them generically, by having a RequestDispatcher that retrieves the item from the ServideProvider and calls the Handle method:

 public TResult Dispatch<TParameter, TResult>(TParameter query)
        where TParameter : IRequest
        where TResult : IResponse
    {
        //Get the approproprite command handler by resolving it from the autofac _serviceProvider based on the IQuery and IQueryResult
        var handler = _serviceProvider.GetService<IRequestHandler<TParameter, TResult>>();
        return handler.Handle(query);
    }

But GetService returns null. I suspect it has something to do with the way items are registered in the container. Here is how I used to register things in Autofac:

builder.RegisterAssemblyTypes(MyAssembly)
            .AsClosedTypesOf(typeof(IRequestHandler<,>))
            .InstancePerLifetimeScope()
            .AsImplementedInterfaces();





Aucun commentaire:

Enregistrer un commentaire