Symfony 4.2 Создание репозитория как сервиса в vendor / acme / demo-bundle - PullRequest
0 голосов
/ 23 марта 2019

Я работаю над сторонним пакетом, который находится в каталоге 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);
    }
}

Это приводит к следующей ошибке:

Репозиторий сущностей «Acme \ DemoBundle \ Repository \ ArticleRepository» реализует «Doctrine \ Bundle \ DoctrineBundle \ Repository \ ServiceEntityRepositoryInterface»,но его служба не может быть найдена.Убедитесь, что сервис существует и помечен как «doctrine.repository_service».

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

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

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

vendor / Acme / demo-bundle / Resources / config / services.yaml

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

отладка bin / console: autowire или debug: контейнер не будет показывать службу.

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

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

Не работалоили.У меня нет впечатления, что расширение вызывается.Я попытался добавить в него конструктор и выполнить команду dump, die в конструкторе, но результаты дампа отсутствуют.

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

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

1 Ответ

0 голосов
/ 25 марта 2019

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

Я добавил в папку 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']

Автоконфигурация и 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
 ---------------- -----------------------------------------------

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

Делайте очистку кеша после каждого изменения ваших сервисов. Даже в dev режим они не перезагружаются после каждого обновления

...