Symfony 4.2 Создание репозитория как сервиса в vendor/acme/demo-bundle

Я работаю над сторонним пакетом, который находится в каталоге vendor/.

У меня есть класс Entity, который выглядит так:

/**
 * @ORM\Entity(repositoryClass = "Acme\DemoBundle\Repository\ArticleRepository")
 * @ORM\Table(name = "acme_demo_article")
 */
class Article

И такой класс репозитория:

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

Это вызывает следующую ошибку:

The "Acme\DemoBundle\Repository\ArticleRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".

Если я удалю репозиторий Class из определения объекта, у меня больше не будет ошибки, и я смогу использовать доктрину как таковую из моего контроллера:

this->getDoctrine()->getRepository(Article::class)->findBy([], null, $limit, ($page - 1) * $limit);

Я попытался добавить репозиторий в качестве службы в определение службы пакета, но это ничего не меняет:

поставщик/Acme/демо-пакет/Ресурсы/config/services.yaml

services:
  Acme\DemoBundle\Repository\:
    resource: '../../Repository/ArticleRepository.php'
    autoconfigure: true
    tags: ['doctrine.repository_service']

bin/console debug:autowire или debug:container не будет отображать службу.

Я также попытался добавить расширение:

namespace Acme\BlogBundle\DependencyInjection;


use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class AcmeBlogExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );
        $loader->load('services.xml');
    }
}

Тоже не работал. У меня нет впечатления, что расширение вызывается. Пробовал добавлять в него конструктор и дамп, умирать в конструкторе, но результатов дампа нет.

Итак, мой вопрос: как мне определить мои репозитории как службу из каталога поставщика?

Исходный код находится здесь: https://github.com/khalid-s/sf4-bundle-test

Вашему пакету требуется расширение в пространстве имен DI для загрузки файлов конфигурации. В вашем тестовом примере это означает создание класса вроде Acme\BlogBundle\DependencyInjection\BlogExtension.

Heah 24.03.2019 16:10

@Heah, я соответственно обновил свое расширение, но оно все равно не работало.

khalid sookia 24.03.2019 18:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
942
1

Ответы 1

После долгих мучений я преуспел в своей задаче. Я не думаю, что это должно быть сделано так, но если это может помочь кому-то...

Я добавил в свою папку DependencyInjection пакета:

class AcmeBlogExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );
        $loader->load('services.yaml');
    }
}

Я создал компилятор (это часть, которую я изо всех сил пытался понять), чтобы зарегистрировать свою службу

class RepositoryCompiler implements CompilerPassInterface
{
    /**
     * @inheritdoc
     */
    public function process(ContainerBuilder $container)
    {
        $container->register('acme_blog.repository', ArticleRepository::class);
    }
}

Я добавил в свой класс Bundle:

class AcmeBlogBundle extends Bundle
{
    /** @info this function normally is useless */
    public function getContainerExtension()
    {
        // This is only useful if the naming convention is not used
        return new AcmeBlogExtension();
    }

    /**
     * @inheritDoc
     */
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(new RepositoryCompiler());

        parent::build($container);
    }
}

И, наконец, сам сервис:

services:
  Acme\BlogBundle\Repository\:
    resource: '../../Repository/*Repository.php'
    autoconfigure: true
    autowire: true
    tags: ['doctrine.repository_service']

Autoconfigure и autowire бесполезны, так как они не учитываются, когда я отлаживаю:контейнер, который выглядит так:

php bin/console debug:container acme

Information for Service "acme_blog.article.repository"
=======================================================

 ---------------- -----------------------------------------------
  Option           Value
 ---------------- -----------------------------------------------
  Service ID       acme_blog.article.repository
  Class            Acme\BlogBundle\Repository\ArticleRepository
  Tags             doctrine.repository_service
  Public           yes
  Synthetic        no
  Lazy             no
  Shared           yes
  Abstract         no
  Autowired        no
  Autoconfigured   no
 ---------------- -----------------------------------------------

Одно очень важное замечание, из-за которого я потерял много времени:

Do clear your cache after every change to your services. Even in dev mode they are not reloaded after every refresh

Другие вопросы по теме