我正在研究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
还有更多文件夹和实体,但与此问题无关。
可以使用如下配置创建该文件夹中的所有类的自动装配:
Acme\FooBundle\:
resource: '../../*/{*Manager.php,Repository/*Repository.php}'
exclude: '../../{Manager/BaseManager.php,Repository/BaseRepository.php}'
autowire: true
但是当你需要添加像doctrine.repository_service
这样的服务标签时,这种配置不再有帮助。没有标签,在控制器中使用时如:
$this->getDoctrine()->getRepository(Bar::class)
或
$this->getDoctrine()->getManager()->getRepository(Bar::class)
它会抛出错误:
" 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']
所以,我想知道是否有一个我无法找到的解决方法,或者我应该手动添加每个服务?
修改 能够在课堂上使用注释是一个很好的功能,所以当它被加载时它会知道"它的标签,但我认为它的工作方式相反,加载一个类,因为它被标记了某个标记。
答案 0 :(得分:1)
您可以在Kernel / Main Bundle Class中自动配置标记:
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');
}
}
答案 1 :(得分:1)
从3.4升级到symfony 4.4之后,我有相同的错误消息。
问题似乎是该实体对@ORM\Entity(repositoryClass="App\Repository\MyRepository")
有注释
而存储库扩展了ServiceEntityRepository
,而在构造函数中则指向实体parent::__construct($registry, MyEntity::class);
。
删除实体上的注释可解决此问题。
答案 2 :(得分:0)
使用PhpStorm 2019.2重构(重新命名)某些实体和相关存储库后,我遇到了相同的错误消息.2重构未更新实体的doc块中的存储库类名称:
* @ORM\Entity(repositoryClass="App\Repository\OldRepository")
因此,我使用了右键单击> Copy Reference
以获取NewRepository
的完全限定名称,并将其粘贴到doc块引用中:
* @ORM\Entity(repositoryClass="\App\Repository\NewRepository")
PhpStorm用反斜杠作为类的前缀,直到尝试了针对此错误的建议解决方案的许多组合之后,我才注意到。我只需要删除反斜杠,错误就消失了:
* @ORM\Entity(repositoryClass="App\Repository\NewRepository")
答案 3 :(得分:0)
您可以标记所有存储库,如下所示:
App\Repository\:
resource: '../src/Repository'
autowire: true
tags: ['doctrine.repository_service']
答案 4 :(得分:0)
感谢@t-van-den-berg 和@arleigh-hix!
从 Symfony 3.4 迁移到 4.4 后,我遇到了这个问题,当时我想将旧存储库与新服务一起使用。
我的解决方案有点变化:
use App\Repository\NewRepository;
//...
/**
* @ORM\Entity(repositoryClass=NewRepository::class)
*/
和服务声明(使用接口):
App\Repository\NewRepository:
arguments:
- "@doctrine"
App\Repository\NewRepositoryInterface: '@App\Repository\NewRepository'