Symfony 4 - 如何在自动装配整个路径时使用服务标签

VMC*_*VMC 6 php service configuration autowired symfony

我正在为 Symfony 4 开发一个包,它的结构如下:

\Acme
  \FooBundle
    \Article
      \Entity
        - Article.php
        - Comment.php
      \Form
        - ArticleType.php
      \Repository
        - ArticleRepository.php
        - CommentRepository.php
      - ArticleManager.php
    \User
      \Entity
        - User.php
      \Repository
        - UserRepository.php
      - UserManager.php
    \SomethingElse
      \Entity
        - SomethingElse.php
      \Repository
        - SomethingElseRepository.php
      - SomethingElseManager.php
Run Code Online (Sandbox Code Playgroud)

还有更多的文件夹和实体,但与问题无关。

可以使用如下配置创建自动装配该文件夹中的所有类:

Acme\FooBundle\:
    resource: '../../*/{*Manager.php,Repository/*Repository.php}'
    exclude: '../../{Manager/BaseManager.php,Repository/BaseRepository.php}'
    autowire: true
Run Code Online (Sandbox Code Playgroud)

但是当您需要添加诸如 的服务标签时doctrine.repository_service,这种配置将无济于事。没有标签,在控制器中使用时,如:

$this->getDoctrine()->getRepository(Bar::class)
Run Code Online (Sandbox Code Playgroud)

或者

$this->getDoctrine()->getManager()->getRepository(Bar::class)
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误:

“Acme\FooBundle\SomethingElse\Repository\SomethingElseRepository”实体仓库实现了“Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface”,但是找不到它的服务。确保服务存在并标记为“doctrine.repository_service”。

问题是,因为它们都驻留在同一个根文件夹中,所以我不允许使用如下配置,因为它会有重复的Acme\FooBundle\键:

Acme\FooBundle\:
    resource: '../../*/{*Manager.php}'
    exclude: '../../{Manager/BaseManager.php}'
    autowire: true

Acme\FooBundle\:
    resource: '../../*/{Repository/*Repository.php}'
    exclude: '../../{Repository/BaseRepository.php}'
    autowire: true
    tags: ['doctrine.repository_service']
Run Code Online (Sandbox Code Playgroud)

所以,我想知道是否有我找不到的解决方法,或者我应该手动添加每一个服务?

编辑: 能够在类中使用注释本来是一个不错的功能,因此当它被加载时它“知道”它的标签,但我认为它反过来工作,加载一个类,因为它被标记为某个标签。

Mak*_*akG 1

您可以在内核/主捆绑包类中自动配置标签:

https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags

<?php

namespace Acme\FooBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class FooBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->registerForAutoconfiguration(EntityRepository::class)
            ->addTag('doctrine.repository_service');
    }
}
Run Code Online (Sandbox Code Playgroud)