Why use the Service Manager in Zend Framework 2? Why use the Service Manager in Zend Framework 2? php php

Why use the Service Manager in Zend Framework 2?


The ServiceManager is by default injected within any ZF2 controller, as it extends the AbstractController implementing the ServiceLocatorAwareInterface interface.

The second approach has a form of "redundancy" because, besides having already access to a ServiceManager instance, whenever you need to share your service among your controllers, you need to configure for each one of them the injection mechanism. As your controllers have already a dependency vis-à-vis the ServiceManager, It would make more sense to use the first approach and register your Domain related Services to the ServiceManager, centralizing thus the access to the Service layer.

Note: The following part of the answer may go beyond the scope of the question, but it aims to provide the "hidden" background of the original one.

Let's assume we're building a complex system, within which low-coupling, re-usability & test-ability are promoted. Our system is multi-layered and we built everything until the service layer. Note that until now we did not consider yet the "MVC" web layer or even opt for a given framework.

Within our Service Layer (I'll consider this layer as it is the one mentioned in the question), we assume that we adopted the principle of separation between the Business Logic and the Object Graph construction (or dependency resolution). So we have probably a couple of complex services that are constructed through factories.

Now that our service layer is built, we decide to "plug" it above ZF2. Naturally, Our services should be accessible from the controllers, as your question illustrated it, we have more than a way for doing it. However, we want to avoid redundancy and leverage what we've already built. Let's assume the following factory :

//The following class is a part of our Service layerpublic class ComplexServiceFactory{    private dependencyA;    private dependencyB;    public function buildComplexService()    {        $service = new ComplexService();        $service->setDependencyA($this->dependecyA);        $service->setDependencyB($this->dependecyB);        return $service;    }}

What we'll do now is just to adjust (actually extend) our factory so that it becomes usable by the ServiceManager logic. This class can be considered as part of the mechanism used to "plug" our system to ZF2 (It's actually an Adapter)

public class SMComplexServiceFactory extends ComplexServiceFactory implements    Zend\ServiceManager\FactoryInterface{    public function createService(ServiceLocatorInterface $sm)    {        $this->setDependencyA($sm->get('dependecyA'));        $this->setDependencyB($sm->get('dependecyB'));        return parent::buildComplexService;    }}

By doing so, we're not bringing up the object graph construction to the MVC layer (otherwise it would be a Separation of Concerns violation and an unnecessary cross-layer coupling). The Service Manager + our "Adapted" factories classes are in some sense our dependency resolution mechanism. The fact is that our System is still portable, we could for example opt for another system (another framework) and have a low dependency vis-à-vis the MVC platform.


Very useful question. He has been raised repeatedly. I think you can get an ACCURATE ANSWER HERE


To add something to @yechabbis answer:

The factory pattern for the ServiceConfiguration is indeed for complex infrastructure or simply to not use closures / callable functions inside the configuration. This is for two reasons:

  • Readability / Cleaner Code
  • Performance

Setting up the factory pattern inside getServiceConfig is nice, clean and fast. No classes are instantiated but will so upon call of the service-key. If, however, you set up services using the closure pattern or callable function, then those classes will always be instantiated, upon every single request!

This probably is just an example thing, but the code you've shown would also best be served as a ViewHelper