Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 16-07-2014 09:22:14

JGreco
Administrateur
Date d'inscription: 22-12-2012
Messages: 432

Factories getServiceLocator dans une factory controller uniquement ?

Bonjour,

Je ne comprend pas pourquoi une factory de Controller doit d'abord faire ceci :

Code:

[lang=php]
$parentLocator = $serviceLocator->getServiceLocator();

 $providerTest = $parentLocator->get('Test\Service\Test');
 return new TestController($providerService);

Alors qu'une factory d'un service non. Je ne trouve pas cela logique et c'est ni implicite ni compréhensible sachant que les deux createService implémentent la même interface et on aussi en dépendance de la méthode la même ServiceLocatorInterface $serviceLocator.


J'aimerai juste comprendre pourquoi en fait.


ZF2 et doctrine addict
profil stack overflow : http://stackoverflow.com/users/3333246/ … ab=profile

Hors ligne

 

#2 16-07-2014 10:12:15

Splyf
Membre
Date d'inscription: 24-10-2013
Messages: 115

Re: Factories getServiceLocator dans une factory controller uniquement ?

Salut,


bin moi je fait pareille quand je crée un service , quelque chose du style

Code:

[lang=php]
public function createService($serviceLocator){
   $parentLocator = $serviceLocator->getServiceLocator();
 
    $b = $parentLocator->get('Test\Service\B');
    return new AService($b);
}

On m'aurai menti a l’issue de mon plein grée yikes ? Comment tu fait toi?

EDIT:
OUlala dsl pas les yeux en fasse des trous de bon matin soiré difficile xD.
Je m'était posé la question il y a un temps et j'était tombé sur ce sujet, que par chance j'ai retrouvé:
http://stackoverflow.com/questions/1491 … hen-not-to


The controller factory is called by a different service manager instance (the "ControllerLoader") to the main one. This is so that the dispatcher can't result in an arbitrary class being instantiated by the main service manager.

As a result, the controller factory's $serviceLocator is not the one you need when you want to retrieve 'greetingService', as 'greetingService' is registered with the main service manager. To get the main server manager from the controller one, you use getServiceLocator() and you now have an instance of the main service manager from which you can get() 'greeting service'

This is known as 'peering'. i.e. the "ControllerLoader" service manager (the one configured via the 'controllers' key in the config or getControllerConfiguration() in a Module class) is set up with the main service manager as a peer.

Perso sa reste encore assez abstrait pour moi...

Dernière modification par Splyf (16-07-2014 10:25:52)

Hors ligne

 

#3 16-07-2014 12:34:28

JGreco
Administrateur
Date d'inscription: 22-12-2012
Messages: 432

Re: Factories getServiceLocator dans une factory controller uniquement ?

Merci pour ta réponse splyf smile tu confirmes ainsi que je suis pas le seul à ne pas comprendre la "logique" derrière ce truc...
Si quelqu'un peut enlever cet abstract de nos têtes lol


ZF2 et doctrine addict
profil stack overflow : http://stackoverflow.com/users/3333246/ … ab=profile

Hors ligne

 

#4 18-07-2014 00:38:43

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Factories getServiceLocator dans une factory controller uniquement ?

Salut à tous les 2. En fait la logique est très simple. Il existe plusieurs service locator dans le ZF2 le parent et celui que l'on connait le plus celui qu'on appelle le ServiceLocator (ou ServiceManager). Sauf que dans le ZF2 il y plusieurs ServiceManager car ils sont spécialisés. En voici quelques exemples :
- FormElementManager
- ControllerManager

Tous ces manager implémentent la même interface et dans le cas des spécialisés ils ont une référence vers le ServiceLocator normal.

En fait ces ServiceManager sont spécialisé pour ne retourner que des objets d'un certains type (je crois que je t'en avais déjà parlé JGreco smile). Si vous allez voir ces 2 classes il y a une methode validatePlugin dans le cas de FormElementManager l'objet retourné par la fabrique doit être de type Zend\Form\ElementInterface (donc un formulaire) et pour ControllerManager Zend\Stdlib\DispatchableInterface (donc un controller). Voila pourquoi il y a des ServiceManager spécialisés ça permet d'être sûr de ce qu'ils nous renvoie ils font le test pour nous.

Ensuite pourquoi lorsque l'on ajoute une factory dans le tableau de config service_manager on a directement le ServiceLocator (normal) et lorsque l'on ajoute une factory dans controllers on a un ControllerManager et dans form_elements un FormElementManager. Tout simplement parce qu'on injecte dans la factory le Manager qui s'occupe de la créer. Dans le cas d'un formulaire c'est FormElementManager. Le problème c'est que FormElementManager ne peut retourner que des objet de type Zend\Form\ElementInterface donc si on l'utilisait dans la factory on ne pourrait récupérer que des instances de formulaire. Comme on veut avoir accès aux services qui sont disponible dans le ServiceLocator principal on fait $parentLocator = $serviceLocator->getServiceLocator(), d'ailleurs dans ce cas $serviceLocator on pourrait l'appeler $formElementManager (faite un var_dump ou un get_class sur $serviceLocator vous verrez).
Voila grosso modo pour l'explication, je ne sais pas si j'ai été clair car il commence à être tard wink.

Petite astuce il est possible de créer un formulaire via une factory dans le tableau de config service_manager et dans ce cas on aura directement le ServiceLocator principal d'injecter. Le seul soucis c'est qu'on ne sera pas certain de récupérer un formulaire wink. Tu peux aussi créer tes propres ServiceManager spécialisé wink

Hors ligne

 

#5 21-07-2014 12:20:44

Splyf
Membre
Date d'inscription: 24-10-2013
Messages: 115

Re: Factories getServiceLocator dans une factory controller uniquement ?

gnééééaaarf >.<

J'ai eu l'impression un moment de me mâchouillé le cerveaux en lisant ces lignes mais je pense avoir compris ^^

En gros, on veut un typage "fort", on fait:
$formElementManager->get('zoupla/pwet');

et on est sur d'avoir un  ElementInterface,

si on accepte un typage faible,
on fait $formElementManager->getServiceLocator('zoupla/pwet');

c'est quelque chose comme sa?

Hors ligne

 

#6 21-07-2014 15:54:16

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Factories getServiceLocator dans une factory controller uniquement ?

Pour être plus exact ça serait $formElementManager->getServiceLocator()->get('zoupla/pwet'). Mais oui en gros c'est ça, ça permet aussi de mieux découper son code en utilisant chaque manager dont c'est le "boulot".

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages