Как настроить внедрение зависимостей для класса репозитория в Symfony 3

Генератор Symfony сгенерировал следующий класс хранилища:

namespace AppBundle\Repository;
use AppBundle\Entity\GroupEntity;

/**
 * GroupEntityRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class GroupEntityRepository extends \Doctrine\ORM\EntityRepository
{


}

services.yml:

group_entity_repository:
         class: AppBundle\Repository\GroupEntityRepository
         arguments: ["@doctrine.orm.entity_manager", AppBundle\Entity\GroupEntity]

Я неправильно настроил services.yml, но не знаю, что использовать в качестве второго аргумента. Итак, я получаю ошибку:

Исправляемая фатальная ошибка: аргумент 2, передаваемый в Doctrine\ORM\EntityRepository::__construct(), должен быть экземпляром Doctrine\ORM\Mapping\ClassMetadata, заданной строки, вызываемой в E:\other\dropbox\Dropbox\programavimas\kodo pavyzdziai\htdocs\users_admin_demo\var\cache\dev\appDevDebugProjectContainer.php в строке 1626 и определенный

Как это исправить? Я не могу видеть в документации, он просто показал код для генератора и окончательно сгенерированного класса, но не конфигурации служб.

1 ответ

Решение

Рекомендуется с Symfony 3.3:

Начиная с Symfony 3.3, в качестве идентификатора службы рекомендуется использовать фактическое имя класса ( прочитайте это и это).

AppBundle\Repository\GroupEntityRepository:
    factory: 'Doctrine\ORM\EntityManagerInterface:getRepository'
    arguments:
        - AppBundle\Entity\GroupEntity

Оригинальный ответ:

Вы можете настроить службу репозитория следующим образом:

group_entity_repository:
    class: AppBundle\Repository\GroupEntityRepository
    factory: ["@doctrine.orm.entity_manager", getRepository]
    arguments:
        - AppBundle\Entity\GroupEntity

Вы, вероятно, никогда не захотите вызывать конструктор хранилища самостоятельно. Поэтому этот подход просто использует entity_manager для получения хранилища. Контейнер службы использует этот код для получения хранилища:

$container->get('doctrine.orm.entity_manager')->getRepository('AppBundle\Entity\GroupEntity');

Начиная с Symfony 3.4, вы можете избежать фабрики и использовать службу TagRepository, которая расширяет класс ServiceEntityRepository вместо непосредственно EntityRepository.

use AppBundle\Entity\GroupEntity;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;

class GroupEntityRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, GroupEntity::class);
    }
}

При использовании этого метода ваша служба будет автоматически зарегистрирована с функцией автоматического подключения.

Вы также можете добиться большего успеха во всех версиях Symfony, используя состав поверх наследования.

final class GroupEntityRepository
{
    /** @var EntityManagerInterface */
    private $entityManager;

    /** @var ObjectRepository */
    private $objectRepository;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
        $this->objectRepository = $this->entityManager->getRepository(GroupEntity::class);
    }

Эта услуга также может быть автоматической проводки. Вы можете пойти дальше, соблюдая принцип SOLID и создав интерфейс. В этой статье есть хорошее объяснение ( Шаблон репозитория в Symfony)

Пример SF 3.4 как сделать в xml:

<service id="vop.sales.payment.entity_repository.billing_status"
                 class="Vop\Sales\PaymentBundle\Entity\BillingStatusRepository">
            <factory service="doctrine.orm.entity_manager" method="getRepository"/>
            <argument>Vop\Sales\PaymentBundle\Entity\BillingStatus</argument>
        </service>
Другие вопросы по тегам