Как настроить внедрение зависимостей для класса репозитория в 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>