Inject multiple services in constructor VS inject a single ServiceFactory in constructor
I would like a tip on what is the best approach between those 2 solutions:
using unity I register N services interfaces/classes
internal class Configurator
{
private static IUnityContainer container = new UnityContainer();
internal static void Configure()
{
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IPhoneService, PhoneService>();
container.RegisterType<IUserService, UserService>();
...
}
internal static T Resolve<T>()
{
return container.Resolve<T>();
}
}
Where all interfaces implements IService
public interface ICustomerService : IService
public interface IPhoneService: IService
public interface IUserService: IService
I've also created a ServiceFactory class
public class ServiceFactory : IServiceFactory
{
public T GetService<T>() where T : IService
{
return Configurator.Resolve<T>();
}
}
now my doubt is:
SOLUTION 1:
public class TestViewModel
{
private ICustomerService _customerService;
private IPhoneService _phoneService;
private IUserService _userService;
public TestViewModel(ICustomerService customerService, IPhoneService phoneService, IUserService userService)
{
_customerService = customerService;
_phoneService = phoneService;
_userService = userService;
}
SOLUTION 2:
public class TestViewModel
{
private IServiceFactory _serviceFactory;
private IUserService _userService;
public IUserService UserService
{
get
{
if(_userService == null)
_userService = _serviceFactory.GetService<IUserService>();
return _userService;
}
}
public MainWindowViewModel(IServiceFactory serviceFactory)
{
_serviceFactory = serviceFactory;
}
Personally i prefer solution 2 because
1) if I must inject a lot of service in a single constructor I can inject only the factory
2) the services are initialized only when requested (in solution 1 they are all initialize in constructors also if the user will never call/use all of them)
Are you agree that solution 2 is better?are there any contraindications?I want to hear some of your opinion...
c# dependency-injection unity-container
add a comment |
I would like a tip on what is the best approach between those 2 solutions:
using unity I register N services interfaces/classes
internal class Configurator
{
private static IUnityContainer container = new UnityContainer();
internal static void Configure()
{
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IPhoneService, PhoneService>();
container.RegisterType<IUserService, UserService>();
...
}
internal static T Resolve<T>()
{
return container.Resolve<T>();
}
}
Where all interfaces implements IService
public interface ICustomerService : IService
public interface IPhoneService: IService
public interface IUserService: IService
I've also created a ServiceFactory class
public class ServiceFactory : IServiceFactory
{
public T GetService<T>() where T : IService
{
return Configurator.Resolve<T>();
}
}
now my doubt is:
SOLUTION 1:
public class TestViewModel
{
private ICustomerService _customerService;
private IPhoneService _phoneService;
private IUserService _userService;
public TestViewModel(ICustomerService customerService, IPhoneService phoneService, IUserService userService)
{
_customerService = customerService;
_phoneService = phoneService;
_userService = userService;
}
SOLUTION 2:
public class TestViewModel
{
private IServiceFactory _serviceFactory;
private IUserService _userService;
public IUserService UserService
{
get
{
if(_userService == null)
_userService = _serviceFactory.GetService<IUserService>();
return _userService;
}
}
public MainWindowViewModel(IServiceFactory serviceFactory)
{
_serviceFactory = serviceFactory;
}
Personally i prefer solution 2 because
1) if I must inject a lot of service in a single constructor I can inject only the factory
2) the services are initialized only when requested (in solution 1 they are all initialize in constructors also if the user will never call/use all of them)
Are you agree that solution 2 is better?are there any contraindications?I want to hear some of your opinion...
c# dependency-injection unity-container
1
This is very much opinion based, so I'd be prepared for your question to be flagged as closed (just fyi) anyway, you still want info, so check out this Article blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern My opinion is that your first version is better, it is explicit and believe when I saw you will come across run time issues when something somewhere hasn't configured a service and you ask for it and bang, stuff doesnt work
– Dave
Nov 21 '18 at 11:23
This is a bit opinion based. That said, the general consensus leans towards using the first approach, because, as van Ivan Mladenov correctly states, your second approach is an implementation of the Service Locator pattern which is generally considered to be an anti-pattern. There are several books on DI that explain why this is an anti-pattern, such as DI: PPP.
– Steven
Nov 21 '18 at 12:00
add a comment |
I would like a tip on what is the best approach between those 2 solutions:
using unity I register N services interfaces/classes
internal class Configurator
{
private static IUnityContainer container = new UnityContainer();
internal static void Configure()
{
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IPhoneService, PhoneService>();
container.RegisterType<IUserService, UserService>();
...
}
internal static T Resolve<T>()
{
return container.Resolve<T>();
}
}
Where all interfaces implements IService
public interface ICustomerService : IService
public interface IPhoneService: IService
public interface IUserService: IService
I've also created a ServiceFactory class
public class ServiceFactory : IServiceFactory
{
public T GetService<T>() where T : IService
{
return Configurator.Resolve<T>();
}
}
now my doubt is:
SOLUTION 1:
public class TestViewModel
{
private ICustomerService _customerService;
private IPhoneService _phoneService;
private IUserService _userService;
public TestViewModel(ICustomerService customerService, IPhoneService phoneService, IUserService userService)
{
_customerService = customerService;
_phoneService = phoneService;
_userService = userService;
}
SOLUTION 2:
public class TestViewModel
{
private IServiceFactory _serviceFactory;
private IUserService _userService;
public IUserService UserService
{
get
{
if(_userService == null)
_userService = _serviceFactory.GetService<IUserService>();
return _userService;
}
}
public MainWindowViewModel(IServiceFactory serviceFactory)
{
_serviceFactory = serviceFactory;
}
Personally i prefer solution 2 because
1) if I must inject a lot of service in a single constructor I can inject only the factory
2) the services are initialized only when requested (in solution 1 they are all initialize in constructors also if the user will never call/use all of them)
Are you agree that solution 2 is better?are there any contraindications?I want to hear some of your opinion...
c# dependency-injection unity-container
I would like a tip on what is the best approach between those 2 solutions:
using unity I register N services interfaces/classes
internal class Configurator
{
private static IUnityContainer container = new UnityContainer();
internal static void Configure()
{
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IPhoneService, PhoneService>();
container.RegisterType<IUserService, UserService>();
...
}
internal static T Resolve<T>()
{
return container.Resolve<T>();
}
}
Where all interfaces implements IService
public interface ICustomerService : IService
public interface IPhoneService: IService
public interface IUserService: IService
I've also created a ServiceFactory class
public class ServiceFactory : IServiceFactory
{
public T GetService<T>() where T : IService
{
return Configurator.Resolve<T>();
}
}
now my doubt is:
SOLUTION 1:
public class TestViewModel
{
private ICustomerService _customerService;
private IPhoneService _phoneService;
private IUserService _userService;
public TestViewModel(ICustomerService customerService, IPhoneService phoneService, IUserService userService)
{
_customerService = customerService;
_phoneService = phoneService;
_userService = userService;
}
SOLUTION 2:
public class TestViewModel
{
private IServiceFactory _serviceFactory;
private IUserService _userService;
public IUserService UserService
{
get
{
if(_userService == null)
_userService = _serviceFactory.GetService<IUserService>();
return _userService;
}
}
public MainWindowViewModel(IServiceFactory serviceFactory)
{
_serviceFactory = serviceFactory;
}
Personally i prefer solution 2 because
1) if I must inject a lot of service in a single constructor I can inject only the factory
2) the services are initialized only when requested (in solution 1 they are all initialize in constructors also if the user will never call/use all of them)
Are you agree that solution 2 is better?are there any contraindications?I want to hear some of your opinion...
c# dependency-injection unity-container
c# dependency-injection unity-container
asked Nov 21 '18 at 11:01
Proxymus89Proxymus89
83
83
1
This is very much opinion based, so I'd be prepared for your question to be flagged as closed (just fyi) anyway, you still want info, so check out this Article blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern My opinion is that your first version is better, it is explicit and believe when I saw you will come across run time issues when something somewhere hasn't configured a service and you ask for it and bang, stuff doesnt work
– Dave
Nov 21 '18 at 11:23
This is a bit opinion based. That said, the general consensus leans towards using the first approach, because, as van Ivan Mladenov correctly states, your second approach is an implementation of the Service Locator pattern which is generally considered to be an anti-pattern. There are several books on DI that explain why this is an anti-pattern, such as DI: PPP.
– Steven
Nov 21 '18 at 12:00
add a comment |
1
This is very much opinion based, so I'd be prepared for your question to be flagged as closed (just fyi) anyway, you still want info, so check out this Article blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern My opinion is that your first version is better, it is explicit and believe when I saw you will come across run time issues when something somewhere hasn't configured a service and you ask for it and bang, stuff doesnt work
– Dave
Nov 21 '18 at 11:23
This is a bit opinion based. That said, the general consensus leans towards using the first approach, because, as van Ivan Mladenov correctly states, your second approach is an implementation of the Service Locator pattern which is generally considered to be an anti-pattern. There are several books on DI that explain why this is an anti-pattern, such as DI: PPP.
– Steven
Nov 21 '18 at 12:00
1
1
This is very much opinion based, so I'd be prepared for your question to be flagged as closed (just fyi) anyway, you still want info, so check out this Article blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern My opinion is that your first version is better, it is explicit and believe when I saw you will come across run time issues when something somewhere hasn't configured a service and you ask for it and bang, stuff doesnt work
– Dave
Nov 21 '18 at 11:23
This is very much opinion based, so I'd be prepared for your question to be flagged as closed (just fyi) anyway, you still want info, so check out this Article blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern My opinion is that your first version is better, it is explicit and believe when I saw you will come across run time issues when something somewhere hasn't configured a service and you ask for it and bang, stuff doesnt work
– Dave
Nov 21 '18 at 11:23
This is a bit opinion based. That said, the general consensus leans towards using the first approach, because, as van Ivan Mladenov correctly states, your second approach is an implementation of the Service Locator pattern which is generally considered to be an anti-pattern. There are several books on DI that explain why this is an anti-pattern, such as DI: PPP.
– Steven
Nov 21 '18 at 12:00
This is a bit opinion based. That said, the general consensus leans towards using the first approach, because, as van Ivan Mladenov correctly states, your second approach is an implementation of the Service Locator pattern which is generally considered to be an anti-pattern. There are several books on DI that explain why this is an anti-pattern, such as DI: PPP.
– Steven
Nov 21 '18 at 12:00
add a comment |
1 Answer
1
active
oldest
votes
That ServiceFactory
class basically acts as a Service Locator which is considered an anti pattern. Reason is that this way your service has way more power than it needs to. By declaring your dependencies in the constructor, you have strict guidelines what you are going to need and use in your class.
If you have too many constructor parameters, it could be a code smell, indicating that your class probably does more than it should and maybe violates the Single Responsibility Principle. It that case, you should think about refactoring that class into smaller subclasses each doing smaller tasks.
My take on the question is that the first solution is better
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
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%2f53410697%2finject-multiple-services-in-constructor-vs-inject-a-single-servicefactory-in-con%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
That ServiceFactory
class basically acts as a Service Locator which is considered an anti pattern. Reason is that this way your service has way more power than it needs to. By declaring your dependencies in the constructor, you have strict guidelines what you are going to need and use in your class.
If you have too many constructor parameters, it could be a code smell, indicating that your class probably does more than it should and maybe violates the Single Responsibility Principle. It that case, you should think about refactoring that class into smaller subclasses each doing smaller tasks.
My take on the question is that the first solution is better
add a comment |
That ServiceFactory
class basically acts as a Service Locator which is considered an anti pattern. Reason is that this way your service has way more power than it needs to. By declaring your dependencies in the constructor, you have strict guidelines what you are going to need and use in your class.
If you have too many constructor parameters, it could be a code smell, indicating that your class probably does more than it should and maybe violates the Single Responsibility Principle. It that case, you should think about refactoring that class into smaller subclasses each doing smaller tasks.
My take on the question is that the first solution is better
add a comment |
That ServiceFactory
class basically acts as a Service Locator which is considered an anti pattern. Reason is that this way your service has way more power than it needs to. By declaring your dependencies in the constructor, you have strict guidelines what you are going to need and use in your class.
If you have too many constructor parameters, it could be a code smell, indicating that your class probably does more than it should and maybe violates the Single Responsibility Principle. It that case, you should think about refactoring that class into smaller subclasses each doing smaller tasks.
My take on the question is that the first solution is better
That ServiceFactory
class basically acts as a Service Locator which is considered an anti pattern. Reason is that this way your service has way more power than it needs to. By declaring your dependencies in the constructor, you have strict guidelines what you are going to need and use in your class.
If you have too many constructor parameters, it could be a code smell, indicating that your class probably does more than it should and maybe violates the Single Responsibility Principle. It that case, you should think about refactoring that class into smaller subclasses each doing smaller tasks.
My take on the question is that the first solution is better
answered Nov 21 '18 at 11:09
Ivan MladenovIvan Mladenov
1,116412
1,116412
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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%2f53410697%2finject-multiple-services-in-constructor-vs-inject-a-single-servicefactory-in-con%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
1
This is very much opinion based, so I'd be prepared for your question to be flagged as closed (just fyi) anyway, you still want info, so check out this Article blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern My opinion is that your first version is better, it is explicit and believe when I saw you will come across run time issues when something somewhere hasn't configured a service and you ask for it and bang, stuff doesnt work
– Dave
Nov 21 '18 at 11:23
This is a bit opinion based. That said, the general consensus leans towards using the first approach, because, as van Ivan Mladenov correctly states, your second approach is an implementation of the Service Locator pattern which is generally considered to be an anti-pattern. There are several books on DI that explain why this is an anti-pattern, such as DI: PPP.
– Steven
Nov 21 '18 at 12:00