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