4 votes

Pourquoi le Servicemanager est-il injecté dans un invokable et non dans un service ?

Je joue actuellement avec le serviceManager de ZF2, et j'essaie de comprendre pourquoi le serviceManager n'injecte pas le sm dans une classe qui implémente ServiceLocatorAwareInterface.

Ma principale question est la suivante : est-ce que je fais bien les choses ou la clé "services" n'est pas destinée aux services qui implémentent ServiceLocatorAwareInterface mais aux services qui n'ont pas besoin d'injection ?

dans Module.php

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

dans MonModule \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;
    }
}

Lorsque j'appelle le service dans un contrôleur

<?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.

    }

}

5voto

Chris Martin Points 66

Vous devez continuer à utiliser la section "invokables" si vous souhaitez utiliser l'interface ServiceManagerAwareInterface et l'injection automatique du Service Manager dans votre service.

Regarder à travers /Zend/ServiceManager/ServiceManager.php Les "services" sont censés être enregistrés comme des objets déjà instanciés auprès du ServiceManager. Lorsque le localisateur de services cherche dans son cache local de services lors de la récupération, il suppose que les "services" sont déjà entièrement configurés et n'injecte pas le sm ou n'exécute aucun initialisateur.

Les "invokables", "factories", "abstract_factories" sont créés à la volée et injectent le sm lorsque les "initializers" sont exécutés sur une instance de service nouvellement créée (voir la fonction create($name)).

3voto

mike Points 580

Oubliez getServiceConfig() et utilisez plutôt la configuration de votre module. Elle est plus rapide et peut être mise en cache :

module.config.php :

'service_manager' => array(
    'invokables' => array(
        'MyModule\Service\Service' => 'MyModule\Service\Service',
    ),
)

MonModule \Service\Service.php :

<?php
namespace MyModule\Service;

use \Zend\ServiceManager\ServiceLocatorInterface;

class Service
{
    public function __invoke(ServiceLocatorInterface $sm)
    {
        // go bananas here :)
    }

    public functiom greet()
    {
        return 'Hello World';
    }
}

n'importe où dans zend2 :

<?php
    $service=$serviceManager->get('MyModule\Service\Service');
    echo $service->greet();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X