What's the difference between using dependency injection with a container and using a service locator?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I understand that directly instantiating dependencies inside a class is considered bad practise. This makes sense as doing so tightly couples everything which in turn makes testing very hard.
Almost all the frameworks I've come across seem to favour dependency injection with a container over using service locators. Both of them seem to achieve the same thing by allowing the programmer to specify what object should be returned when a class requires a dependency.
What's the difference between the two? Why would I choose one over the other?
dependency-injection ioc-containers service-locator
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
I understand that directly instantiating dependencies inside a class is considered bad practise. This makes sense as doing so tightly couples everything which in turn makes testing very hard.
Almost all the frameworks I've come across seem to favour dependency injection with a container over using service locators. Both of them seem to achieve the same thing by allowing the programmer to specify what object should be returned when a class requires a dependency.
What's the difference between the two? Why would I choose one over the other?
dependency-injection ioc-containers service-locator
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
I understand that directly instantiating dependencies inside a class is considered bad practise. This makes sense as doing so tightly couples everything which in turn makes testing very hard.
Almost all the frameworks I've come across seem to favour dependency injection with a container over using service locators. Both of them seem to achieve the same thing by allowing the programmer to specify what object should be returned when a class requires a dependency.
What's the difference between the two? Why would I choose one over the other?
dependency-injection ioc-containers service-locator
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I understand that directly instantiating dependencies inside a class is considered bad practise. This makes sense as doing so tightly couples everything which in turn makes testing very hard.
Almost all the frameworks I've come across seem to favour dependency injection with a container over using service locators. Both of them seem to achieve the same thing by allowing the programmer to specify what object should be returned when a class requires a dependency.
What's the difference between the two? Why would I choose one over the other?
dependency-injection ioc-containers service-locator
dependency-injection ioc-containers service-locator
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 4 hours ago
tom6025222tom6025222
261
261
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
tom6025222 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
(This is actually a pretty good question.)
When the object itself is responsible for requesting its dependencies, as opposed to accepting them through a constructor, it's hiding some essential information. It's only mildly better than the very tightly-coupled case of using new to instantiate its dependencies. It reduces coupling because you can in fact change the dependencies it gets, but it still has a dependency it can't shake: the service locator. That becomes the thing that everything is dependent on.
A container that supplies dependencies through constructor arguments gives the most clarity. We see right up front that an object needs both an AccountRepository, and a PasswordStrengthEvaluator. When using a service locator, that information is less immediately apparent. You'd see right away a case where an object has, oh, 17 dependencies, and say to yourself, "Hmm, that seems like a lot. What's going on in there?" Calls to a service locator can be spread around the various methods, and hide behind conditional logic, and you might not realize you have created a "God class" -- one that does everything. Maybe that class could be refactored into 3 smaller classes that are more focused, and hence more testable.
Now consider testing. If an object uses a service locator to get its dependencies, your test framework will also need a service locator. In a test, you'll configure the service locator to supply the the dependencies to the object under test -- maybe a FakeAccountRepository and a VeryForgivingPasswordStrengthEvaluator, and then run the test. But that's more work than specifying dependencies in the object's constructor. And your test framework also becomes dependent on the service locator. It's another thing you have to configure in every test, which makes writing tests less attractive.
Look up "Serivce Locator is an Anti-Pattern" for Mark Seeman's article about it. If you're in the .Net world, get his book. It's very good.
That's a great explanation, thank you.
– tom6025222
2 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "131"
};
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
});
}
});
tom6025222 is a new contributor. Be nice, and check out our Code of Conduct.
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%2fsoftwareengineering.stackexchange.com%2fquestions%2f390755%2fwhats-the-difference-between-using-dependency-injection-with-a-container-and-us%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
(This is actually a pretty good question.)
When the object itself is responsible for requesting its dependencies, as opposed to accepting them through a constructor, it's hiding some essential information. It's only mildly better than the very tightly-coupled case of using new to instantiate its dependencies. It reduces coupling because you can in fact change the dependencies it gets, but it still has a dependency it can't shake: the service locator. That becomes the thing that everything is dependent on.
A container that supplies dependencies through constructor arguments gives the most clarity. We see right up front that an object needs both an AccountRepository, and a PasswordStrengthEvaluator. When using a service locator, that information is less immediately apparent. You'd see right away a case where an object has, oh, 17 dependencies, and say to yourself, "Hmm, that seems like a lot. What's going on in there?" Calls to a service locator can be spread around the various methods, and hide behind conditional logic, and you might not realize you have created a "God class" -- one that does everything. Maybe that class could be refactored into 3 smaller classes that are more focused, and hence more testable.
Now consider testing. If an object uses a service locator to get its dependencies, your test framework will also need a service locator. In a test, you'll configure the service locator to supply the the dependencies to the object under test -- maybe a FakeAccountRepository and a VeryForgivingPasswordStrengthEvaluator, and then run the test. But that's more work than specifying dependencies in the object's constructor. And your test framework also becomes dependent on the service locator. It's another thing you have to configure in every test, which makes writing tests less attractive.
Look up "Serivce Locator is an Anti-Pattern" for Mark Seeman's article about it. If you're in the .Net world, get his book. It's very good.
That's a great explanation, thank you.
– tom6025222
2 hours ago
add a comment |
(This is actually a pretty good question.)
When the object itself is responsible for requesting its dependencies, as opposed to accepting them through a constructor, it's hiding some essential information. It's only mildly better than the very tightly-coupled case of using new to instantiate its dependencies. It reduces coupling because you can in fact change the dependencies it gets, but it still has a dependency it can't shake: the service locator. That becomes the thing that everything is dependent on.
A container that supplies dependencies through constructor arguments gives the most clarity. We see right up front that an object needs both an AccountRepository, and a PasswordStrengthEvaluator. When using a service locator, that information is less immediately apparent. You'd see right away a case where an object has, oh, 17 dependencies, and say to yourself, "Hmm, that seems like a lot. What's going on in there?" Calls to a service locator can be spread around the various methods, and hide behind conditional logic, and you might not realize you have created a "God class" -- one that does everything. Maybe that class could be refactored into 3 smaller classes that are more focused, and hence more testable.
Now consider testing. If an object uses a service locator to get its dependencies, your test framework will also need a service locator. In a test, you'll configure the service locator to supply the the dependencies to the object under test -- maybe a FakeAccountRepository and a VeryForgivingPasswordStrengthEvaluator, and then run the test. But that's more work than specifying dependencies in the object's constructor. And your test framework also becomes dependent on the service locator. It's another thing you have to configure in every test, which makes writing tests less attractive.
Look up "Serivce Locator is an Anti-Pattern" for Mark Seeman's article about it. If you're in the .Net world, get his book. It's very good.
That's a great explanation, thank you.
– tom6025222
2 hours ago
add a comment |
(This is actually a pretty good question.)
When the object itself is responsible for requesting its dependencies, as opposed to accepting them through a constructor, it's hiding some essential information. It's only mildly better than the very tightly-coupled case of using new to instantiate its dependencies. It reduces coupling because you can in fact change the dependencies it gets, but it still has a dependency it can't shake: the service locator. That becomes the thing that everything is dependent on.
A container that supplies dependencies through constructor arguments gives the most clarity. We see right up front that an object needs both an AccountRepository, and a PasswordStrengthEvaluator. When using a service locator, that information is less immediately apparent. You'd see right away a case where an object has, oh, 17 dependencies, and say to yourself, "Hmm, that seems like a lot. What's going on in there?" Calls to a service locator can be spread around the various methods, and hide behind conditional logic, and you might not realize you have created a "God class" -- one that does everything. Maybe that class could be refactored into 3 smaller classes that are more focused, and hence more testable.
Now consider testing. If an object uses a service locator to get its dependencies, your test framework will also need a service locator. In a test, you'll configure the service locator to supply the the dependencies to the object under test -- maybe a FakeAccountRepository and a VeryForgivingPasswordStrengthEvaluator, and then run the test. But that's more work than specifying dependencies in the object's constructor. And your test framework also becomes dependent on the service locator. It's another thing you have to configure in every test, which makes writing tests less attractive.
Look up "Serivce Locator is an Anti-Pattern" for Mark Seeman's article about it. If you're in the .Net world, get his book. It's very good.
(This is actually a pretty good question.)
When the object itself is responsible for requesting its dependencies, as opposed to accepting them through a constructor, it's hiding some essential information. It's only mildly better than the very tightly-coupled case of using new to instantiate its dependencies. It reduces coupling because you can in fact change the dependencies it gets, but it still has a dependency it can't shake: the service locator. That becomes the thing that everything is dependent on.
A container that supplies dependencies through constructor arguments gives the most clarity. We see right up front that an object needs both an AccountRepository, and a PasswordStrengthEvaluator. When using a service locator, that information is less immediately apparent. You'd see right away a case where an object has, oh, 17 dependencies, and say to yourself, "Hmm, that seems like a lot. What's going on in there?" Calls to a service locator can be spread around the various methods, and hide behind conditional logic, and you might not realize you have created a "God class" -- one that does everything. Maybe that class could be refactored into 3 smaller classes that are more focused, and hence more testable.
Now consider testing. If an object uses a service locator to get its dependencies, your test framework will also need a service locator. In a test, you'll configure the service locator to supply the the dependencies to the object under test -- maybe a FakeAccountRepository and a VeryForgivingPasswordStrengthEvaluator, and then run the test. But that's more work than specifying dependencies in the object's constructor. And your test framework also becomes dependent on the service locator. It's another thing you have to configure in every test, which makes writing tests less attractive.
Look up "Serivce Locator is an Anti-Pattern" for Mark Seeman's article about it. If you're in the .Net world, get his book. It's very good.
edited 3 hours ago
answered 3 hours ago
Carl RaymondCarl Raymond
33714
33714
That's a great explanation, thank you.
– tom6025222
2 hours ago
add a comment |
That's a great explanation, thank you.
– tom6025222
2 hours ago
That's a great explanation, thank you.
– tom6025222
2 hours ago
That's a great explanation, thank you.
– tom6025222
2 hours ago
add a comment |
tom6025222 is a new contributor. Be nice, and check out our Code of Conduct.
tom6025222 is a new contributor. Be nice, and check out our Code of Conduct.
tom6025222 is a new contributor. Be nice, and check out our Code of Conduct.
tom6025222 is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Software Engineering Stack Exchange!
- 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%2fsoftwareengineering.stackexchange.com%2fquestions%2f390755%2fwhats-the-difference-between-using-dependency-injection-with-a-container-and-us%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