Geeks With Blogs
Kyle Burns

The Service Locator pattern and Dependency Injection clearly take a much different approach to achieving Inversion of Control and these differences often lead to philosophical discussions about which is better.  Rather than tag either as "better", it is much better to look at the advantages and disadvantages that each bring to the table and understand that at different times and in different scenarios each will assert an edge over the other that makes it the most appropriate choice for that scenario. 

One of the biggest advantages that I see in using Dependency Injection (at least when contructor injection is used as opposed to property injection) is that the component provides a very clear advertisement in the form of constructor arguments as to what external services that it needs in order to complete its job.  This also allows the component to be independent of the mechanism used to provide Inversion of Control because it does not need to be aware of any IoC container or service locator implementation.  If you're not using some sort of framework that is responsible for "building up" components and ensuring dependencies are resolved, the injection approach can also lead to having to invent ways to pass references down through several layers of application code in order to make the reference available to the code that depends upon it, which makes changes at the component level that require the introduction of a new dependency bubble changes through multiple levels.

The biggest advantage that I see in the Service Locator pattern is a direct counter to the advantage of using Dependency Injection.  Because the component does not advertise the dependencies that it has on external services to complete its work the code adheres more closely to the concept of encapsulation.  By advertising external dependencies required to complete work, it can be said that that components using Dependency Injection reveal a bit more of "how" the work is done instead of leaving the entire focus on "what" work is to be completed.  Using the Service Locator approach, there is no need to ensure that service references are passed from layer to layer that may not need them.  This advantage to some degree is countered by the fact that many developers using Inversion of Control will also be using some sort of framework that will handle resolution of dependencies.  Additionally, by removing the explicit advertisement of dependencies on object construction the risk of finding that a necessary service has not been registered late in the process increases and the component cannot "fail early".

All other things being equal, I find that my preferences lean to the explicit model provided with constructor injection and allow whatever IoC container that I am using handle many of the drawbacks of this approach.  This allows me to quickly look at the method signature of the constructor for any class that I have built using this model and understand what it needs to get its job done - a big advantage when trying to quickly understand problems with production code.  There are some times when you find that your component MUST support a public constructor with no arguments and others when it is not required but does make sense to do so.  In these cases, the Service Locator becomes a valuable tool to make services available to your component.

Posted on Friday, April 27, 2012 8:31 AM | Back to top


Comments on this post: Dependency Injection vs. Service Locator

# re: Dependency Injection vs. Service Locator
Requesting Gravatar...
Interesting post, Kyle.

I prefer the Dependency Injection pattern too, for the reasons you describe above. I think that fundamentally it comes back to Design by Contract: "I require these pre-conditions [dependencies] to be met in order to function as expected."

I think your argument in favour of Service Locator (that it is an example of encapsulation) is flawed. Encapsulation is primarily about keeping data and their associated behaviours together; Wikipedia also mentions that it can be used to restrict access to an object's components, which Steve McConnell refers to as "information hiding" in his book "Code Complete". The Service Locator pattern is nothing to do with encapsulation, nor does it explicitly buy you better encapsulation. Service Locator has so many disadvantages, such as limiting reusability and tightly-coupling your application to your container-of-choice, that I really think it's use does more harm than good.

One example of the situation you describe in your closing paragraph, where you "MUST support a public constructor with no arguments", is with ASP.NET WebForms: the Page class (amongst others) requires a parameterless constructor to be defined, which limits your options for dependency injection. This can be resolved without resorting to a Service Locator by making your Page classes very simple UI-level objects that follow an MVP sort of pattern with the Presenter logic stored in classes in another assembly. You can then build your Presenters with whatever dependencies you need and resolve them all in one go in the Page class's constructor. The same pattern can be applied to WinForms as well.

Mark Seeman's book, Dependency Injection in .NET, is a really good read on this topic and convincingly argues for Service Locator to be considered an anti-pattern. It also covers the WebForms scenario described above better and in more detail than I am able to do in a blog comment.

http://www.amazon.co.uk/Dependency-Injection-NET-Mark-Seemann/dp/1935182501
Left by Alastair Smith on Apr 27, 2012 5:43 PM

# re: Dependency Injection vs. Service Locator
Requesting Gravatar...
I admit. I have not been on this web page in a long time… however it was another joy to see It is such an important topic and ignored by so many. even professionals. professionals. I thank you to help making people more aware of possible issues. More Information

Left by James on Feb 06, 2018 6:43 AM

Your comment:
 (will show your gravatar)


Copyright © Kyle Burns | Powered by: GeeksWithBlogs.net