我有一个由服务层和存储库层组成的应用程序。对于服务和存储库,我已经声明了接口,我为控制器中的服务注入了接口,并且服务注入了存储库的接口。这一切都是在autowire设置为true的情况下完成的。
当我在其中一个注入的服务上调用方法时,一切正常,只要我不调用需要其中一个注入的存储库的函数。当我尝试调用使用其中一个存储库的函数时,我收到以下错误:
无法自动装配服务“AppBundle \ Repository \ TestRepository”:方法“Doctrine \ ORM \ EntityRepository :: __ construct()”的参数“$ em”必须具有类型提示或明确赋予值。
现在我认为这与我必须从我的存储库扩展的EntityRepository类这一事实有关,因为当我看到构造函数时,它看起来像这样:
class TestRepository extends EntityRepository implements TestRepositoryInterface
{
public function __construct(
EntityManager $em,
Mapping\ClassMetadata $class
) {
parent::__construct($em, $class);
}
/**
* @return string
*/
public function getTest(): string
{
return 'This is a test';
}
}
其中显然包含错误消息中提到的$ em参数。我不知道如何解决这个问题。 目前我的服务和存储库在services.yml中配置相同,但由于服务似乎有效,我认为这不是问题。我是否需要为我的存储库禁用autowire并在services.yml中手动配置它们,或者我只是遗漏了一些非常明显的东西?
答案 0 :(得分:7)
无法直接实例化存储库。您需要使用EntityManager :: getRepository
因此,您需要在services.yml中定义您的存储库
// services.yml
AppBundle\Repository\UserRepository:
factory: 'doctrine.orm.entity_manager:getRepository'
arguments: ['AppBundle\Entity\User']
然后autowire注射应该有效。
我很想知道autowire是否真的流行起来。它本质上是令人沮丧的,因为有些服务就像魔术一样连接,而其他服务需要人工干预,这可能会导致一些混乱。
答案 1 :(得分:1)
实际上,有一种方法可以做到,但我不确定我们是否可以/应该这样做
class TestRepository extends EntityRepository
{
// Constructor for autowiring
public function __construct(EntityManager $em)
{
parent::__construct($em, $em->getClassMetadata(Test::class));
}