将存储库、实体管理器注入服务的最佳实践是什么?
我想我至少有三种方法可以做到。
1.通过构造函数注入存储库、管理器
通过这种方式,可以很容易地对服务进行测试。您所需要的只是将模拟的依赖项传递给构造函数,这样您就做好了准备。
class TestService
{
public function __construct(MyEntityRepository $my, AnotherEntityRepository $another, EntityManager $manager)
{
$this->my = $my;
$this->another = $another;
$this->manager = $manager;
}
public function doSomething()
{
$item = $this->my->find(<...>);
<..>
$this->manager->persist($item);
$this->manager->flush();
}
}
2.只传递EntityManager
如果您需要来自同一个管理器的4个存储库,那么测试起来就有点困难了。我认为通过这种方式,您必须模拟manager的getRepository调用。
class TestService
{
public function __construct(EntityManager $manager)
{
$this->manager = $manager;
}
public function doSomething()
{
$item = $this->manager->getRepository('my')->find(<...>);
<..>
$this->manager->persist($item);
$this->manager->flush();
}
}
3.通过整个注册表
通过这种方式,您不会获得条令事件订阅者的循环引用异常,但更难模拟所有内容。
此外,这是sensiolabs见解不会给我注入EntityManager带来架构冲突的唯一方法。
class TestService
{
public function __construct(RegistryInterface $registry)
{
$this->doctrine = $registry;
}
public function doSomething()
{
$item = $this->registry->getManager()->getRepository('my')->find(<...>);
<..>
$this->registry->getManager()->persist($item);
$this->registry->getManager()->flush();
}
}
做到这一点的最佳做法是什么?为什么?
我总是尝试注入尽可能具体的服务。
这意味着我总是注入存储库,因为这在编写测试时更容易。否则,您也必须模拟注册表和/或管理器。
我知道这是旧的,但我只是想加上我的2美分。我关注Matthias Noback在这两篇博客文章中所说的:
- 注入存储库而不是EntityManager
- 注入ManagarRegistry而不是EntityManager
因此,每当我需要找到实体时,我都会注入特定的存储库,但如果我需要调用flush
、persist
或remove
,我也会注入ManagerRegistry,因为否则你必须在所有存储库中为它们设置代理函数。