Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the Servicemanager injected in a invokable and not a service

I'm currently playing with the ZF2 serviceManager, and i'm trying to figure out why the serviceManager doesn't inject the sm in a class that implements ServiceLocatorAwareInterface.

My main question is am i doing it right or is the "services" key not for services that implement ServiceLocatorAwareInterface but for services that don't need injection?

in Module.php

public function getServiceConfig() {
    return array(
        'invokables' => array(
            'myService1' => 'MyModule\Service\Service'
        ),
        'services' => array(
            'myService2' => new MyModule\Service\Service(),
        ),
    );
}

in MyModule\Service\Service.php

namespace MyModule\Service;

use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;

class Service implements ServiceManagerAwareInterface
{
    /**
     * @var ServiceManager
     */
    protected $serviceManager = NULL;

    /**
     * Retrieve service manager instance
     *
     * @return ServiceManager
     */
    public function getServiceManager()
    {
        return $this->serviceManager;
    }

    /**
     * Set service manager instance
     *
     * @param ServiceManager $serviceManager
     */
    public function setServiceManager(ServiceManager $serviceManager)
    {
        $this->serviceManager = $serviceManager;
    }
}

When i call the service in a controller

<?php

namespace MyModule\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{

    public function IndexAction() {

        $service1   = $this->getServiceLocator()->get('myService1');
        $sm1        = $service1->getServiceManager(); 
        //$sm1 becomes a object of Zend\ServiceManager\ServiceManager
        //In other words i now can access the SM from within my service.

        $service2   = $this->getServiceLocator()->get('myService2');
        $sm2        = $service2->getServiceManager(); 
        //$sm2 becomes NULL
        //The service isn't aware of the SM and can't access it.

    }

}
like image 414
Ponsjuh Avatar asked Feb 18 '23 16:02

Ponsjuh


1 Answers

You should continue to use the "invokables" section if you'd like to utilize the ServiceManagerAwareInterface and the automatic injection of the Service Manager into your service.

Looking through /Zend/ServiceManager/ServiceManager.php, "services" are meant to be registered as already instantiated objects with the ServiceManager. When the service locator looks up in it's local cache of services during retrieval, it assumes that "services" are already fully set up and does not inject the sm or run any initializers.

"invokables", "factories", "abstract_factories" are created on the fly and injects the sm when the "initializers" are run on a newly created service instance (see function create($name)).

like image 75
Chris Martin Avatar answered Mar 05 '23 18:03

Chris Martin