L'injection de dépendance dans l'entité de référentiel
Est-il un moyen simple d'injecter une dépendance dans chaque instance de référentiel dans Doctrine2 ?
J'ai essayé d'écouter le loadClassMetadata
de l'événement et à l'aide de l'injection par mutateur sur le référentiel, mais naturellement, cela a entraîné une boucle infinie que l'appel à la getRepository
dans l'événement déclenché le même événement.
Après avoir pris un coup d'oeil à la Doctrine\ORM\EntityManager::getRepository
méthode, il semble que les référentiels ne sont pas à l'aide de l'injection de dépendance à tous, au lieu qu'ils sont instanciés au niveau de la fonction:
public function getRepository($entityName)
{
$entityName = ltrim($entityName, '\\');
if (isset($this->repositories[$entityName])) {
return $this->repositories[$entityName];
}
$metadata = $this->getClassMetadata($entityName);
$customRepositoryClassName = $metadata->customRepositoryClassName;
if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $metadata);
} else {
$repository = new EntityRepository($this, $metadata);
}
$this->repositories[$entityName] = $repository;
return $repository;
}
Des idées ?
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez un personnalisé EntityManager vous pourriez remplacer le
getRepository
méthode. Car ce n'est pas leloadClassMetadata
cas, vous ne rencontrerez pas dans une boucle infinie.Il faut d'abord passer de la dépendance à votre personnalisé EntityManager, et vous devez alors passer à l'objet de référentiel à l'aide de l'injection par mutateur.
J'ai répondu comment utiliser un EntityManager ici, mais je vais répliquer à la réponse ci-dessous:
1 - Remplacer le
doctrine.orm.entity_manager.class
paramètre de point personnalisé gestionnaire d'entités (qui doit s'étendreDoctrine\ORM\EntityManager
.)2 - Votre entité personnalisée gestionnaire doit remplacer la
create
méthode afin qu'elle retourne une instance de votre classe. Voir mon exemple ci-dessous, et la note de la dernière ligne concernantMyEntityManager
:Vous aurez également besoin de
use
suivantes dans votre classe:Modifier
Depuis le gestionnaire d'entité par défaut est créé à partir de la
create
méthode, vous ne pouvez pas simplement injecter un service en elle. Mais puisque vous faites une entité personnalisée manager, vous pouvez le fil jusqu'au conteneur de services et d'injecter quelque dépendances dont vous avez besoin.Ensuite, depuis le substituée
getRepository
méthode que vous pourriez faire quelque chose comme$repository->setFoo($this->foo)
. C'est un exemple très simple - vous pouvez d'abord vérifier si$repository
a unsetFoo
méthode avant de l'appeler. La mise en œuvre est à vous, mais cela montre comment utiliser l'injection par mutateur pour un dépôt.vendor/symfony/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml
mais je suis un peu confus sur la façon d'ajouter l'injection que je suis en utilisant yml pour mon définitions des services deProblème est que les classes de dépôt ne font pas partie de la Symfony2 base de code qu'ils font partie de Doctrine2, de sorte qu'ils ne profitent pas de la DIC; c'est pourquoi vous ne pouvez pas aller pour injection en un seul endroit pour tous les référentiels.
Je vous conseille d'utiliser une approche différente. Par exemple, vous pouvez créer une couche de service de dépôts et effectivement injecter la classe que vous souhaitez grâce à une usine dans cette couche.
Sinon, vous pouvez également définir des référentiels comme les services de cette façon:
Une solution qui pourrait centraliser l'ensemble de l'appel de méthode est d'écrire un DIC balise et une passe de compilateur de le gérer et de marquer l'ensemble des services de dépôt.
C'est un YAML version de Aldo de réponse, juste au cas où vous utilisez YAML configurations au lieu de XML
Et antérieures à la version 2.8:
Aussi, comme une note, entity_manager_name est un paramètre facultatif. Je veux la valeur par défaut pour mon usage particulier, donc j'ai juste laissé vide (juste au cas où que j'ai jamais renommer la valeur par défaut du gestionnaire).
Je viens de définir mon propre RepositoryFactory classe
my_service.orm_repository.robo_repository_factory
, avec notamment @service_container injectionEt ajouter vérifier et régler le conteneur de service, par exemple:
Créer compilateur classe
Après que tout
EntityRepository
avecContainerAwareInterface
a @service_containerDepuis Symfony 3.3+ et 2017 vous pouvez utiliser les services.
À la place d'autres solutions proposées ici, qui conduisent à:
Vous pouvez le faire...
Propre Façon de Dépendance via le Constructeur de l'Injection comme dans tout autre Service
Lire la suite dans le Post
Vous pouvez lire plus à ce tutoriel détaillé avec claire des exemples de code dans Comment utiliser le Référentiel avec la Doctrine de Service dans Symfony post.
Vous pouvez réellement créer votre propre
DefaultRepository extends EntityRepository
, construire de toutes les dépendances que vous avez besoin et de le définir comme un défautRepository
avec: