Il y avait 2 questions ici indiquant l'injection de l'ensemble du conteneur de service devrait résoudre ce problème. Mais questionner ... Voir ci-dessous (nocturne différence entre TYP 2 & 3) ...
ESSAYER 1 STROND> P> public function __construct(ContainerInterface $container) {
$this->container = $container;
}
4 Réponses :
Cela se produit car votre contexte de sécurité dépend de cet auditeur, probablement via le gestionnaire d'entité étant injecté dans un fournisseur d'utilisateurs. La meilleure solution consiste à injecter le conteneur dans l'auditeur et à accéder au contexte de sécurité paresseusement. P>
Je n'aime généralement pas injecter tout le conteneur dans un service, mais faites une exception avec les auditeurs de doctrine, car ils sont chargés avec impatience et doivent donc être aussi paresseux que possible. P>
Hmm, a du sens, mais je ne comprends pas comment "essayer 2" devrait échouer quand 3 réussit. Oui, son "paresseux" mais une variable d'instance gâche le fonctionnement d'une autre classe? Hmm ...
Le conteneur tient une trace de quels services il s'agit en cours de création. Si get () code> est appelé l'un de ces services qu'il est déjà en cours de création, une exception de référence circulaire est lancée. C'est pourquoi vous obtenez cette exception lorsque vous appelez le contexte de sécurité de l'intérieur du constructeur, mais pas autrement. Lorsque le constructeur est appelé, le conteneur travaille déjà sur la création du contexte de sécurité.
Injecter le conteneur n'est jamais «la meilleure solution». Je pense que la meilleure approche serait d'utiliser «Services paresseux».
Essayé de rendre les dépendances sur mon EventsDubscriber Code> paresseusement chargé, mais qui a toujours entraîné la même référence circulaire: symfony.com/doc/current/service_container/lazy_services.html y aurait-il une autre façon de ne pas injecter le conteneur dans le service?
La raison "2" échoue et "3" ne fait pas partie du fait de l'option 2, vous essayez d'accéder au contexte de sécurité immédiatement du conteneur lorsqu'il n'est probablement pas encore peuplé. p>
Au mieux que je puisse dire, Symfony2 analyse par la configuration et instancie le service après l'autre, puis se déplace sur la manipulation du reste de la demande. p>
Cela signifie que vous ne pouvez pas nécessairement accéder aux différentes parties du conteneur, car elle peut les charger dans un ordre différent. Vous disposez donc du pointeur de la mémoire sur le conteneur et de le stocker, mais laissez ensuite le cadre terminé la construction du conteneur complet avant d'essayer d'y accéder. Une exception notable à ceci est lorsque vous injectionnez directement le service dans un autre service, à quel point le conteneur veille à ce qu'il ait ce service chargé d'abord. p>
Vous pouvez voir les effets de cela en faisant deux services. A et B. A est passé B et B est passé A. Maintenant, vous avez une référence circulaire. Si vous avez plutôt transmis le conteneur dans A et B, vous ne pouvez pas accéder à A de B et B de A Sans problème. P>
AS de Symfony 2.6 Ce problème devrait être corrigé. Une demande de traction vient d'être acceptée dans le maître. Votre problème est décrit ici. https://github.com/symfony/symfony/pull/11690
AS de Symfony 2.6, vous peut injecter le Exemple d'utilisation 2.6: P> votre configuration: em> p> < votre auditeur em> p> p> p> P> P> Security.Token_storage code> dans votre auditeur. Ce service contiendra le jeton utilisé par le SecurityContext Code> dans <= 2.5. Dans 3.0 Ce service remplacera le SecurityContext :: getToken () code> complètement. Vous pouvez voir une liste de modifications de base ici: http://symfony.com/blog/new-in-symfony-2-6-Security-Component-improvements#depecated-Le-Security-Context-Service P>
Vous devez toujours essayer d'éviter l'injection de conteneur directement à vos services. P>
Je pense que la meilleure solution possible au problème «référence circulaire» ainsi qu'aux problèmes de performances possibles, seraient d'utiliser « Services paresseux » Disponible à partir de Symfony 2.3. P>
Il suffit de marquer votre dépendance comme J'espère que cela aide, acclamations. P> paresseux code> dans votre configuration de conteneur de service et installez le pont proxyManager (rechercher des détails dans la documentation des services paresseux ci-dessus). P>
Cela m'a aidé dans mon cas. Mais il est un peu étrange que Ocramius / Proxy-Manager Code> Bibliothèque (nécessaire pour que cette fonction soit capable d'utiliser) nécessite deux bibliothèques Zendframework. Compte tenu de ces dépendances, je doute que l'utilisation de chargement paresseux pour pas trop gros graphiques de service donne un avantage rapide.
Exemple de code complet s'il vous plaît. La référence circulaire signifie généralement que vous essayez d'injecter un service qui est déjà injecté d'une autre manière dans la même classe. (Le problème le plus populaire est le gestionnaire d'entité dans les auditeurs de doctrine)