Last Updated: February 25, 2016
· aimfeld

Dependency injection container (DiC) vs. service locator (SL)

There seems to be a lot of confusion between the terms dependency injection container (DiC) and service locator (SL). Part of the confusion arises, because the same service (e.g. Zend\ServiceManager, Zend\Di\Di or ZendDiCompiler) can be used either as a DiC or as an SL.

Using such a service as a DiC means that the service injects the dependencies from outside into a class. In a pure DiC scenario, the DiC is used only during bootstrapping. It creates the controller class and injects its dependencies from outside, without being used in the controller (Register Resolve Release pattern).

Using the same service as an SL means pulling the dependencies of a class from inside that class. Some experts advise against the service locator pattern. However, in Zend Framework 2, the service locator pattern is commonly used, as you can pull services from inside the controllers with $this->serviceLocator->get().

For code examples of both DiC and SL, have a look at my ZendDiCompiler ZF2 module!

2 Responses
Add your response

Can the controllers be the composition root for the DiC? I don't quite understand how all the dependencies can be resolved in the bootstrapping, what does that mean? Stick all the resolutions into the index.php?

I like AngularJS's style of DI, that I understand. I don't understand PHP's style of DI.

over 1 year ago ·

Maybe this section in the ZendDiCompiler documentation helps clarifying.
It's a little complicated and a lot of confusion comes from using terms differently in different articles. Let's define composition root as "the single place in your application where the composition of the object graphs for your application take place". If you inject the DiC into your controller class and pull the controller dependencies from in there, there is no composition root, since object graphs are now constructed in many places with $dic->get($className) calls. I call this using a DiC as a service locator.

The purist way is to construct the whole object graph in a single place (composition root). In a ZF2 application, this means creating controller instances using a DiC in Module.php, and not inject the DiC into controllers or into their dependencies. Here's a code example.

public function onBootstrap(MvcEvent $mvcEvent)
    $serviceManager = $mvcEvent->getApplication()->getServiceManager(); 
    $this->zendDiCompiler = $serviceManager->get('ZendDiCompiler'); 

public function getControllerConfig()
    return array(
        'factories' => array(
            'MyModule\Controller\Index'    => function () {
                $controllerClass = 'MyModule\Controller\IndexController';
                return $this->zendDiCompiler->get($controllerClass);
over 1 year ago ·