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

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

 Ugo T.21 июл. 2016 г., 15:34
НайденныйЭта тема, это, вероятно, может помочь вам.

Ответы на вопрос(3)

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

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);
    }

Эта услуга также может быть автоматической проводки. Вы можете пойти дальше, уважаяТВЕРДЫЙ принцип и создать интерфейс. В этой статье есть хорошее объяснение (Шаблон репозитория в 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>
Решение Вопроса

Рекомендуется с 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');
 Tobias Xy21 июл. 2016 г., 15:49
Здесь вы можете найти информацию об использовании фабрик для определения сервиса:symfony.com/doc/current/components/dependency_injection/... Он не является специфичным для репозиториев, но должен объяснить, как это работает в целом.
 beltouche11 окт. 2017 г., 21:48
Последние достижения в Symfony устарели, так что вы можете / должны просто использовать имя класса и удалить этот ключ.
 Cerad21 июл. 2016 г., 15:58
Другим хорошим источником информации является панель поиска Google. Не быть чрезмерно скупым, но этот вопрос задавался и отвечался десятки (если не сотни) раз. Попробуйте скопировать / вставить свой заголовок в Google и посмотреть, что получится. Та же самая техника поиска может быть использована и для многих других вещей.
 Darius.V21 июл. 2016 г., 16:44
@Cerad - собственно сейчас я вижу подобное, но перед тем как спросить попробовал гуглить и не увидел. Или я, возможно, видел такие вещи, как «фабрика» и думал, что это не то, что мне нужно, и поэтому пропустил такие ответы. Я работал над проектом с Symfony, и я не помню заводские вещи для этого. Или, может быть, не заметил: /
 Tobias Xy12 окт. 2017 г., 11:11
Спасибо, я обновил ответ.
 Darius.V05 дек. 2018 г., 16:22
Теперь я не могу найти такой же пример в XML. Я пытаюсь уже 45 минут.
 Darius.V21 июл. 2016 г., 15:45
Ты бог. Хорошо, теперь, как мне найти эту информацию? Я думаю, моя проблема - найти простую информацию очень долго. Я работал над этой страницей:symfony.com/doc/current/book/...  И если я получаю хранилище по-вашему, я получаю сообщение об ошибке «Вы запросили несуществующий сервис« appbundle \ entity \ groupentity »». Но когда я спрашиваю $ groupRepo = $ this-> container-> get ('group_entity_repository'); - оно работает.

Ваш ответ на вопрос