.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.
c# .net generics dependency-injection core
add a comment |
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.
c# .net generics dependency-injection core
add a comment |
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.
c# .net generics dependency-injection core
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
c# .net generics dependency-injection core
edited Nov 15 at 14:39
Steven
125k17211325
125k17211325
asked Nov 9 at 19:03
Taras
153
153
add a comment |
add a comment |
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.
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
add a comment |
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?
In your original example, you are executing this callGetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>>
which is not the same asGetService<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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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?
In your original example, you are executing this callGetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>>
which is not the same asGetService<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
add a comment |
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?
In your original example, you are executing this callGetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>>
which is not the same asGetService<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
add a comment |
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?
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?
answered Nov 9 at 19:40
Taras
153
153
In your original example, you are executing this callGetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>>
which is not the same asGetService<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
add a comment |
In your original example, you are executing this callGetService<IRequestHandler<IRequest<IEnumerable<GetUsersResult>>, IEnumerable<GetUsersResult>>>
which is not the same asGetService<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
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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