.NET Core dependency injection, resolve generic interface









up vote
1
down vote

favorite












I am having trouble with asp.net core dependency injection, I cannot resolve generic interface from IServiceProvider. Here is my setup:



Generic interfaces:



public interface IRequest<out TResponse> ...

public interface IRequestHandler<TRequest, TResult>
where TRequest : IRequest<TResult> ...


Concrete implementation:



public class GetUsersQuery : IRequest<IEnumerable<GetUsersResult>> ...

public abstract class RequestHandler<TRequest, TResult>
: IRequestHandler<TRequest, TResult>
where TRequest : IRequest<TResult> ...

public class GetUsersQueryHandler
: RequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>> ...


Then I have a service factory were I register dependency injection like this:



public static void ConfigureServices(IServiceCollection services)

services.AddTransient<IRequestHandler<GetUsersQuery,
IEnumerable<GetUsersResult>>, GetUsersQueryHandler>();



I can successfully resolve my handler like this:



var handler = 
_services.GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>();


However, I would like to have a generic method in this factory that receives concrete implementation of IRequest and returns the appropriate handler without knowing the exact type beforehand, something like this:



public Task<TResult> Execute<TResult>(IRequest<TResult> request)

var handler =
_services.GetService<IRequestHandler<IRequest<TResult>, TResult>>();
return handler.ExecuteAsync(request);



And call this method like this:



_serviceFactory.Execute(new GetUsersQuery());


Unfortunately this doesn't work, handler is not resolved and is null. I feel like this should be possible though.



Could you please tell me what I am doing wrong and how to achieve this?
Thank you very much in advance.










share|improve this question



























    up vote
    1
    down vote

    favorite












    I am having trouble with asp.net core dependency injection, I cannot resolve generic interface from IServiceProvider. Here is my setup:



    Generic interfaces:



    public interface IRequest<out TResponse> ...

    public interface IRequestHandler<TRequest, TResult>
    where TRequest : IRequest<TResult> ...


    Concrete implementation:



    public class GetUsersQuery : IRequest<IEnumerable<GetUsersResult>> ...

    public abstract class RequestHandler<TRequest, TResult>
    : IRequestHandler<TRequest, TResult>
    where TRequest : IRequest<TResult> ...

    public class GetUsersQueryHandler
    : RequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>> ...


    Then I have a service factory were I register dependency injection like this:



    public static void ConfigureServices(IServiceCollection services)

    services.AddTransient<IRequestHandler<GetUsersQuery,
    IEnumerable<GetUsersResult>>, GetUsersQueryHandler>();



    I can successfully resolve my handler like this:



    var handler = 
    _services.GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>();


    However, I would like to have a generic method in this factory that receives concrete implementation of IRequest and returns the appropriate handler without knowing the exact type beforehand, something like this:



    public Task<TResult> Execute<TResult>(IRequest<TResult> request)

    var handler =
    _services.GetService<IRequestHandler<IRequest<TResult>, TResult>>();
    return handler.ExecuteAsync(request);



    And call this method like this:



    _serviceFactory.Execute(new GetUsersQuery());


    Unfortunately this doesn't work, handler is not resolved and is null. I feel like this should be possible though.



    Could you please tell me what I am doing wrong and how to achieve this?
    Thank you very much in advance.










    share|improve this question

























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am having trouble with asp.net core dependency injection, I cannot resolve generic interface from IServiceProvider. Here is my setup:



      Generic interfaces:



      public interface IRequest<out TResponse> ...

      public interface IRequestHandler<TRequest, TResult>
      where TRequest : IRequest<TResult> ...


      Concrete implementation:



      public class GetUsersQuery : IRequest<IEnumerable<GetUsersResult>> ...

      public abstract class RequestHandler<TRequest, TResult>
      : IRequestHandler<TRequest, TResult>
      where TRequest : IRequest<TResult> ...

      public class GetUsersQueryHandler
      : RequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>> ...


      Then I have a service factory were I register dependency injection like this:



      public static void ConfigureServices(IServiceCollection services)

      services.AddTransient<IRequestHandler<GetUsersQuery,
      IEnumerable<GetUsersResult>>, GetUsersQueryHandler>();



      I can successfully resolve my handler like this:



      var handler = 
      _services.GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>();


      However, I would like to have a generic method in this factory that receives concrete implementation of IRequest and returns the appropriate handler without knowing the exact type beforehand, something like this:



      public Task<TResult> Execute<TResult>(IRequest<TResult> request)

      var handler =
      _services.GetService<IRequestHandler<IRequest<TResult>, TResult>>();
      return handler.ExecuteAsync(request);



      And call this method like this:



      _serviceFactory.Execute(new GetUsersQuery());


      Unfortunately this doesn't work, handler is not resolved and is null. I feel like this should be possible though.



      Could you please tell me what I am doing wrong and how to achieve this?
      Thank you very much in advance.










      share|improve this question















      I am having trouble with asp.net core dependency injection, I cannot resolve generic interface from IServiceProvider. Here is my setup:



      Generic interfaces:



      public interface IRequest<out TResponse> ...

      public interface IRequestHandler<TRequest, TResult>
      where TRequest : IRequest<TResult> ...


      Concrete implementation:



      public class GetUsersQuery : IRequest<IEnumerable<GetUsersResult>> ...

      public abstract class RequestHandler<TRequest, TResult>
      : IRequestHandler<TRequest, TResult>
      where TRequest : IRequest<TResult> ...

      public class GetUsersQueryHandler
      : RequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>> ...


      Then I have a service factory were I register dependency injection like this:



      public static void ConfigureServices(IServiceCollection services)

      services.AddTransient<IRequestHandler<GetUsersQuery,
      IEnumerable<GetUsersResult>>, GetUsersQueryHandler>();



      I can successfully resolve my handler like this:



      var handler = 
      _services.GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>();


      However, I would like to have a generic method in this factory that receives concrete implementation of IRequest and returns the appropriate handler without knowing the exact type beforehand, something like this:



      public Task<TResult> Execute<TResult>(IRequest<TResult> request)

      var handler =
      _services.GetService<IRequestHandler<IRequest<TResult>, TResult>>();
      return handler.ExecuteAsync(request);



      And call this method like this:



      _serviceFactory.Execute(new GetUsersQuery());


      Unfortunately this doesn't work, handler is not resolved and is null. I feel like this should be possible though.



      Could you please tell me what I am doing wrong and how to achieve this?
      Thank you very much in advance.







      c# .net generics dependency-injection core






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 15 at 14:39









      Steven

      125k17211325




      125k17211325










      asked Nov 9 at 19:03









      Taras

      153




      153






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          This design might originate from this blog post. That same blog post shows a solution for your exact problem:



          public TResult Process<TResult>(IQuery<TResult> query)

          var handlerType = typeof(IQueryHandler<,>)
          .MakeGenericType(query.GetType(), typeof(TResult));

          dynamic handler = container.GetInstance(handlerType);

          return handler.Handle((dynamic)query);



          This translates, in your case, to the following:



          public Task<TResult> Execute<TResult>(IRequest<TResult> request)

          var handlerType = typeof(IRequestHandler<,>)
          .MakeGenericType(request.GetType(), typeof(TResult));

          dynamic handler = _services.GetRequiredService(handlerType);

          return handler.ExecuteAsync((dynamic)query);



          About the use of dynamic, the blog post states:




          Unfortunately we need to call the Handle method using reflection (by using the C# 4.0 dymamic keyword in this case), because at this point it is impossible to cast the handler instance, since the generic TQuery argument is not available at compile time.







          share|improve this answer




















          • Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
            – Taras
            Nov 14 at 15:47











          • Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
            – Taras
            Nov 14 at 15:50











          • You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
            – Steven
            Nov 15 at 14:37

















          up vote
          0
          down vote













          I think I have found one way of doing this, execute method could be declared like this:



          public Task<TResult> Execute<TRequest, TResult>(TRequest request)
          where TRequest : IRequest<TResult>

          var handler = _services.GetService<IRequestHandler<TRequest, TResult>>();
          return handler.ExecuteAsync(request);



          And used like this:



          _serviceFactory.Execute<GetUsersQuery, IEnumerable<GetUsersResult>>(query);


          This is a bit ugly, because I have to specify both request and result types for Execute method, would be better to just use _serviceFactory.Execute(query), but I suppose it might not be possible?






          share|improve this answer




















          • In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
            – Alexander Pope
            Nov 9 at 19:53











          • I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
            – Alexander Pope
            Nov 9 at 20:07










          • Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
            – Taras
            Nov 14 at 15:57










          • First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
            – Alexander Pope
            2 days ago










          • See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
            – Alexander Pope
            2 days ago










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53231845%2fnet-core-dependency-injection-resolve-generic-interface%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          This design might originate from this blog post. That same blog post shows a solution for your exact problem:



          public TResult Process<TResult>(IQuery<TResult> query)

          var handlerType = typeof(IQueryHandler<,>)
          .MakeGenericType(query.GetType(), typeof(TResult));

          dynamic handler = container.GetInstance(handlerType);

          return handler.Handle((dynamic)query);



          This translates, in your case, to the following:



          public Task<TResult> Execute<TResult>(IRequest<TResult> request)

          var handlerType = typeof(IRequestHandler<,>)
          .MakeGenericType(request.GetType(), typeof(TResult));

          dynamic handler = _services.GetRequiredService(handlerType);

          return handler.ExecuteAsync((dynamic)query);



          About the use of dynamic, the blog post states:




          Unfortunately we need to call the Handle method using reflection (by using the C# 4.0 dymamic keyword in this case), because at this point it is impossible to cast the handler instance, since the generic TQuery argument is not available at compile time.







          share|improve this answer




















          • Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
            – Taras
            Nov 14 at 15:47











          • Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
            – Taras
            Nov 14 at 15:50











          • You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
            – Steven
            Nov 15 at 14:37














          up vote
          0
          down vote



          accepted










          This design might originate from this blog post. That same blog post shows a solution for your exact problem:



          public TResult Process<TResult>(IQuery<TResult> query)

          var handlerType = typeof(IQueryHandler<,>)
          .MakeGenericType(query.GetType(), typeof(TResult));

          dynamic handler = container.GetInstance(handlerType);

          return handler.Handle((dynamic)query);



          This translates, in your case, to the following:



          public Task<TResult> Execute<TResult>(IRequest<TResult> request)

          var handlerType = typeof(IRequestHandler<,>)
          .MakeGenericType(request.GetType(), typeof(TResult));

          dynamic handler = _services.GetRequiredService(handlerType);

          return handler.ExecuteAsync((dynamic)query);



          About the use of dynamic, the blog post states:




          Unfortunately we need to call the Handle method using reflection (by using the C# 4.0 dymamic keyword in this case), because at this point it is impossible to cast the handler instance, since the generic TQuery argument is not available at compile time.







          share|improve this answer




















          • Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
            – Taras
            Nov 14 at 15:47











          • Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
            – Taras
            Nov 14 at 15:50











          • You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
            – Steven
            Nov 15 at 14:37












          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          This design might originate from this blog post. That same blog post shows a solution for your exact problem:



          public TResult Process<TResult>(IQuery<TResult> query)

          var handlerType = typeof(IQueryHandler<,>)
          .MakeGenericType(query.GetType(), typeof(TResult));

          dynamic handler = container.GetInstance(handlerType);

          return handler.Handle((dynamic)query);



          This translates, in your case, to the following:



          public Task<TResult> Execute<TResult>(IRequest<TResult> request)

          var handlerType = typeof(IRequestHandler<,>)
          .MakeGenericType(request.GetType(), typeof(TResult));

          dynamic handler = _services.GetRequiredService(handlerType);

          return handler.ExecuteAsync((dynamic)query);



          About the use of dynamic, the blog post states:




          Unfortunately we need to call the Handle method using reflection (by using the C# 4.0 dymamic keyword in this case), because at this point it is impossible to cast the handler instance, since the generic TQuery argument is not available at compile time.







          share|improve this answer












          This design might originate from this blog post. That same blog post shows a solution for your exact problem:



          public TResult Process<TResult>(IQuery<TResult> query)

          var handlerType = typeof(IQueryHandler<,>)
          .MakeGenericType(query.GetType(), typeof(TResult));

          dynamic handler = container.GetInstance(handlerType);

          return handler.Handle((dynamic)query);



          This translates, in your case, to the following:



          public Task<TResult> Execute<TResult>(IRequest<TResult> request)

          var handlerType = typeof(IRequestHandler<,>)
          .MakeGenericType(request.GetType(), typeof(TResult));

          dynamic handler = _services.GetRequiredService(handlerType);

          return handler.ExecuteAsync((dynamic)query);



          About the use of dynamic, the blog post states:




          Unfortunately we need to call the Handle method using reflection (by using the C# 4.0 dymamic keyword in this case), because at this point it is impossible to cast the handler instance, since the generic TQuery argument is not available at compile time.








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 11 at 20:26









          Steven

          125k17211325




          125k17211325











          • Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
            – Taras
            Nov 14 at 15:47











          • Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
            – Taras
            Nov 14 at 15:50











          • You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
            – Steven
            Nov 15 at 14:37
















          • Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
            – Taras
            Nov 14 at 15:47











          • Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
            – Taras
            Nov 14 at 15:50











          • You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
            – Steven
            Nov 15 at 14:37















          Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
          – Taras
          Nov 14 at 15:47





          Thank you! This works, I think this approach is better than the one in my answer. I haven't seen this blog post before, your implementation is indeed almost the same.
          – Taras
          Nov 14 at 15:47













          Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
          – Taras
          Nov 14 at 15:50





          Also, I wonder - is it possible to register all handlers in ASP.NET Core like in your example: container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
          – Taras
          Nov 14 at 15:50













          You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
          – Steven
          Nov 15 at 14:37




          You will have to do it manually by iterating through the assembly types, filter out non query handlers, and register them by their interface. There's no built-in support for auto-registration.
          – Steven
          Nov 15 at 14:37












          up vote
          0
          down vote













          I think I have found one way of doing this, execute method could be declared like this:



          public Task<TResult> Execute<TRequest, TResult>(TRequest request)
          where TRequest : IRequest<TResult>

          var handler = _services.GetService<IRequestHandler<TRequest, TResult>>();
          return handler.ExecuteAsync(request);



          And used like this:



          _serviceFactory.Execute<GetUsersQuery, IEnumerable<GetUsersResult>>(query);


          This is a bit ugly, because I have to specify both request and result types for Execute method, would be better to just use _serviceFactory.Execute(query), but I suppose it might not be possible?






          share|improve this answer




















          • In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
            – Alexander Pope
            Nov 9 at 19:53











          • I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
            – Alexander Pope
            Nov 9 at 20:07










          • Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
            – Taras
            Nov 14 at 15:57










          • First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
            – Alexander Pope
            2 days ago










          • See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
            – Alexander Pope
            2 days ago














          up vote
          0
          down vote













          I think I have found one way of doing this, execute method could be declared like this:



          public Task<TResult> Execute<TRequest, TResult>(TRequest request)
          where TRequest : IRequest<TResult>

          var handler = _services.GetService<IRequestHandler<TRequest, TResult>>();
          return handler.ExecuteAsync(request);



          And used like this:



          _serviceFactory.Execute<GetUsersQuery, IEnumerable<GetUsersResult>>(query);


          This is a bit ugly, because I have to specify both request and result types for Execute method, would be better to just use _serviceFactory.Execute(query), but I suppose it might not be possible?






          share|improve this answer




















          • In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
            – Alexander Pope
            Nov 9 at 19:53











          • I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
            – Alexander Pope
            Nov 9 at 20:07










          • Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
            – Taras
            Nov 14 at 15:57










          • First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
            – Alexander Pope
            2 days ago










          • See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
            – Alexander Pope
            2 days ago












          up vote
          0
          down vote










          up vote
          0
          down vote









          I think I have found one way of doing this, execute method could be declared like this:



          public Task<TResult> Execute<TRequest, TResult>(TRequest request)
          where TRequest : IRequest<TResult>

          var handler = _services.GetService<IRequestHandler<TRequest, TResult>>();
          return handler.ExecuteAsync(request);



          And used like this:



          _serviceFactory.Execute<GetUsersQuery, IEnumerable<GetUsersResult>>(query);


          This is a bit ugly, because I have to specify both request and result types for Execute method, would be better to just use _serviceFactory.Execute(query), but I suppose it might not be possible?






          share|improve this answer












          I think I have found one way of doing this, execute method could be declared like this:



          public Task<TResult> Execute<TRequest, TResult>(TRequest request)
          where TRequest : IRequest<TResult>

          var handler = _services.GetService<IRequestHandler<TRequest, TResult>>();
          return handler.ExecuteAsync(request);



          And used like this:



          _serviceFactory.Execute<GetUsersQuery, IEnumerable<GetUsersResult>>(query);


          This is a bit ugly, because I have to specify both request and result types for Execute method, would be better to just use _serviceFactory.Execute(query), but I suppose it might not be possible?







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 9 at 19:40









          Taras

          153




          153











          • In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
            – Alexander Pope
            Nov 9 at 19:53











          • I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
            – Alexander Pope
            Nov 9 at 20:07










          • Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
            – Taras
            Nov 14 at 15:57










          • First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
            – Alexander Pope
            2 days ago










          • See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
            – Alexander Pope
            2 days ago
















          • In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
            – Alexander Pope
            Nov 9 at 19:53











          • I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
            – Alexander Pope
            Nov 9 at 20:07










          • Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
            – Taras
            Nov 14 at 15:57










          • First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
            – Alexander Pope
            2 days ago










          • See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
            – Alexander Pope
            2 days ago















          In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
          – Alexander Pope
          Nov 9 at 19:53





          In your original example, you are executing this call GetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>> which is not the same as GetService<IRequestHandler<GetUsersQuery, IEnumerable<GetUsersResult>>>
          – Alexander Pope
          Nov 9 at 19:53













          I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
          – Alexander Pope
          Nov 9 at 20:07




          I think you should reconsider your design. You are attempting to implement the ServiceLocator pattern through the DI container. The sane way of solving your problem is to use factories when instead: stackoverflow.com/questions/31950362/….
          – Alexander Pope
          Nov 9 at 20:07












          Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
          – Taras
          Nov 14 at 15:57




          Hi, thank you for your feedback. This design seems simple and flexible enough, and it requires very little code, especially with the approach that Steven suggested. What are the downsides in your opinion?
          – Taras
          Nov 14 at 15:57












          First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
          – Alexander Pope
          2 days ago




          First, ServiceLocator is considered by many to be an antipatern. Secondly, will you ever depend on other parameters for dependency resolution? Right now you only care about generic type parameters, but what if you start depending on bools, integers or strings? Refactoring this design would be difficult because of explicitly using the service locator instead of relying on constructor injection and factories. Maybe try asking on softwareengineering.stackexchange.com for feedback on your design.
          – Alexander Pope
          2 days ago












          See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
          – Alexander Pope
          2 days ago




          See also this question and the linked questions from it stackoverflow.com/questions/47843787/…
          – Alexander Pope
          2 days ago

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53231845%2fnet-core-dependency-injection-resolve-generic-interface%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Use pre created SQLite database for Android project in kotlin

          Darth Vader #20

          Ondo