web-dev-qa-db-fra.com

Symfony - injecter doctrine dépôt en service

selon Comment injecter un référentiel dans un service dans Symfony2? c'est comme

acme.custom_repository:
    class: Doctrine\ORM\EntityRepository
    factory: ['@doctrine.orm.entity_manager', getRepository]
    arguments:
        - 'Acme\FileBundle\Model\File'

mais je reçois une exception

Service "acme.custom_repository" non valide: la classe "EntityManager5aa02de170f88_546a8d27f194334ee012bfe64f629947b07e4919__CG __\Doctrine\ORM\EntityManager" n'existe pas.

Comment puis-je faire cela dans Symfony 3.4?

mise à jour:

EntityClass est en fait un FQCN de classe valide (également utilisé la référence de copie sur phpstorm pour être sûr), juste renommé parce qu'un nom de société est dedans :). quand même mis à jour.

solution

BlueM's solution fonctionne parfaitement. Si vous n'utilisez pas le câblage automatique, voici la définition du service:

Acme\AcmeBundle\Respository\MyEntityRepository:
    arguments:
        - '@Doctrine\Common\Persistence\ManagerRegistry'
        - Acme\AcmeBundle\Model\MyEntity # '%my_entity_class_parameter%'
9
Brucie Alpha

Comme vous utilisez Symfony 3.4, vous pouvez utiliser une approche beaucoup plus simple, en utilisant ServiceEntityRepository. Implémentez simplement votre dépôt, laissez-le extend classe ServiceEntityRepository et vous pouvez simplement l'injecter. (Au moins lors de l'utilisation du câblage automatique - je ne l'ai pas utilisé avec une configuration DI classique, mais je suppose que cela devrait également fonctionner.)

En d'autres termes:

namespace App\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

class ExampleRepository extends ServiceEntityRepository
{
    /**
     * @param ManagerRegistry $managerRegistry
     */
    public function __construct(ManagerRegistry $managerRegistry)
    {
        parent::__construct($managerRegistry, YourEntity::class);
    }
}

Maintenant, sans aucune configuration DI, vous pouvez injecter le référentiel où vous voulez, y compris les méthodes du contrôleur.

Une mise en garde (qui s'applique également à la façon dont vous essayez d'injecter le référentiel): si la connexion Doctrine est réinitialisée, vous aurez une référence à un référentiel périmé. Mais à mon humble avis, c'est un risque J'accepte, sinon je ne pourrai pas injecter le dépôt directement.

20
BlueM

Vérifiez que les arguments sont une classe valide (avec FQCN ou avec une simplification de bundle) comme exemple:

acme.custom_repository:
    class: Doctrine\ORM\EntityRepository
    factory: 
        - '@doctrine.orm.entity_manager'
        - getRepository
    arguments:
        - Acme\MainBundle\Entity\MyEntity

ou

acme.custom_repository:
    class: Doctrine\ORM\EntityRepository
    factory: 
        - '@doctrine.orm.entity_manager'
        - getRepository
    arguments:
        - AcmeMainBundle:MyEntity

J'espère que cette aide

3
Matteo

Créez correctement le référentiel personnalisé

Tout d'abord, vous devez créer la classe personnalisée de référentiel qui étend le référentiel par défaut à partir de doctrine:

use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
   // your own methods
}

Ensuite, vous avez besoin de cette annotation dans la classe d'entité:

/**
 * @ORM\Entity(repositoryClass="MyDomain\Model\UserRepository")
 */

Ensuite, vous définissez le référentiel dans le fichier .yml:

custom_repository:
        class: MyDomain\Model\UserRepository
        factory: ["@doctrine", getRepository]
        arguments:
          - Acme\FileBundle\Model\File

Assurez-vous que dans la définition de votre référentiel class pointe vers votre classe de référentiel personnalisée et non vers Doctrine\ORM\EntityRepository.

Injectez des services personnalisés dans votre référentiel personnalisé:

Sur votre référentiel personnalisé, créez des setters personnalisés pour vos services

utilisez Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
    protected $paginator;

    public function setPaginator(PaginatorInterface $paginator)
    {
        $this->paginator = $paginator;
    }
}

Ensuite, injectez-les comme ceci:

custom_repository:
        class: MyDomain\Model\UserRepository

        factory: ["@doctrine", getRepository]
        arguments:
          - Acme\FileBundle\Model\File
        calls:
          - [setPaginator, ['@knp_paginator']]

Injectez votre référentiel dans un service:

my_custom_service:
    class: Acme\FileBundle\Services\CustomService
    arguments:
        - "@custom_repository"
0
etudor