Why are Service Locator frameworks often called Dependency Injection Containers?

Software Engineering Asked by Snail Cadet on November 27, 2020

First, here’s how I understand these two concepts: Service Locators are not Dependency Injection. Both Service Locators and Dependency Injection are applications of Inversion of Control. This is the understanding I reached after reading Martin Fowler’s write-up on the topic. If my understanding is incorrect, please explain how.

In many places online, I have seen what are clearly Service Locators referred to as Dependency Injection libraries or frameworks. For example, Simple Injector calls itself "an open-source dependency injection (DI) library for .NET." However, in its quick start page, an example is shown which clearly demonstrates that Simple Injector is a Service Locator. Microsoft provides the .NET Core namespace "Microsoft.Extensions.DependencyInjection," which is clearly a Service Locator as well. An Essential .NET blog post from 2016 titled "Dependency Injection with .NET Core" explains in detail how to use the ".NET Core DI framework" to register services!

There are true (as I understand them) dependency injection containers around, of course, such as Ninject, which actually performs automated dependency injection.

Am I misunderstanding the distinction between these concepts? If not, how did they come to be so thoroughly mixed up?

3 Answers

Service location vs dependency injection

Service Locators are not Dependency Injection.

I disagree, but I think you intend to say/focus on something different than what I'm disagreeing with.

First of all, Philip Kendall's answer is correct that abstract-to-concrete type registration is the same in either case, the only real difference is how to access those registrations.

Internally, a DI framework uses a service locator to find the injectable instance/type. In essence, a service locator is the dictionary that contains the abstract-to-concrete type registrations that have been registered. Logically, any DI framework is required to keep track of those registrations so that it can then retrieve them when necessary.

Why are Service Locator frameworks often called Dependency Injection Containers?

What you call Dependency Injection is really just Service Location, but with the added feature of automatically locating services based on a constructor signature1 and acting as a factory for all of its registered types, instead of forcing the developer (= user of your framework) to directly request the services from your framework's service locator and being required to manually construct the dependency graph.

Note: whether the developer locates services inside the constructor body, or calls the constructor manually after having located the services, is an irrelevant distinction here. In either case, they've had to manually construct the dependency graph by supplying the services to classes that depend on them.

So the short answer to your question is "because DI frameworks are essentially service locators with a few extra features that abstract the location of registered services".


1 Due to an objection raised in the comments, I agree that DI can be done without a service locator, but I have yet to come across a single DI framework that does so. I suspect doing DI as a framework without SL is going to put so much effort on the developer that the framework doesn't really add meaningful value anymore.

I'd be interested in seeing an example of DI without SL in a DI framework.

Since this question focuses on DI frameworks and what we call them; I stand by my claim within the context that the question defines.

Answered by Flater on November 27, 2020

A first difference is: Not every service locator is a dependency injection container; a service locator can be used for another purpose than dependency injection. This can even create some issues such as hidden dependencies (see Fowler’s explanation on SL vs DI), to the point that some consider SL to be an anti-pattern (but again imho it depends on how it is used in the end).

A second and even more important difference is that dependency injection containers are more than just service locators: they are also service composers.

For example, in the SimpleInjector example to which you referred, you can see that the container is also informed about how to instantiate the service (singleton vs factory), and that it itself composes the service CancelOrderService, automatically resolving and injecting its known dependency with the help of the dependency map configured in the container. And this last feature is the real benefit of a DI framework that saves you from writing you a lot of boring and tedious boilerplate code every time you want to instantiate an object that relies on dependencies!

Answered by Christophe on November 27, 2020

You've got to get the knowledge of your services into your framework, whether that be a "dependency injection" framework or a "service locator" framework, and you do that some variant of

framework.register(abstractType, concreteType)

no matter what framework you're using. The difference is in how you get things out of the framework again:

  • With a service locator, every time you want an instance of a service, you call framework.get(abstractType).
  • With dependency injection, you pass the dependencies down from one layer to the next, and let your framework do the job of wiring up those dependencies. (You may need a few calls to framework.get at the top level, but you shouldn't have one every time you want a service).

Certainly the latter is how Microsoft.Services.DependencyInjection is intended to be used, and it's not really any different from how NInject is used.

Answered by Philip Kendall on November 27, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP