Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour,
Je ne comprend pas pourquoi une factory de Controller doit d'abord faire ceci :
[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.
Hors ligne
Salut,
bin moi je fait pareille quand je crée un service , quelque chose du style
[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 ? 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
Merci pour ta réponse splyf 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
Hors ligne
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 ). 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 .
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 . Tu peux aussi créer tes propres ServiceManager spécialisé
Hors ligne
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
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
Pages: 1