2017-09-05 50 views
3

在Symfony2中(在这种情况下为2.8)在将服务注入到另一个服务时被认为是最佳实践?Symfony2中的依赖注入最佳实践

/** 
* Checker constructor. 
* @param EntityManager $em 
* @param EventDispatcherInterface $dispatcher 
*/ 
public function __construct(EntityManager $em, EventDispatcherInterface $dispatcher) 
{ 
    $this->repoUser = $em->getRepository(User::class); 
    $this->repoPurchase = $em->getRepository(Purchase::class); 
    $this->repoTicket = $em->getRepository(Ticket::class); 
    $this->dispatcher = $dispatcher; 
} 

/** 
* Checker constructor. 
* @param UserRepository $ur 
* @param PurchaseRepository $pr 
* @param TicketRepository $tr 
* @param EventDispatcherInterface $dispatcher 
*/ 
public function __construct(UserRepository $ur, PurchaseRepository $pr, TicketRepository $tr, EventDispatcherInterface $dispatcher) 
{ 
    $this->repoUser = $ur; 
    $this->repoPurchase = $pr; 
    $this->repoTicket = $tr; 
    $this->dispatcher = $dispatcher; 
} 

,或者使用setter方法明确和services.yml单独设置参数呢?

我想知道等式的性能部分是什么。

+0

你可能**最好是第一个,原因是1)更灵活,如果你以后需要其他存储库(或减少一些),因为你只需要触摸该类而不是'services.yml'(这个是可辩论的,但**我认为它更干净)2)ServiceContainer只需查找一个引用而不是几个。 – ccKep

回答

7

这两种情况都有优点和缺点。

  • 性能而言,这两种选择都是平等的,因为你得到的仓库情况下,仅当你要求你的服务的一个实例。无论你手动完成,还是由DI自动完成。由于提供了here,

    容器是懒惰的:它没有实例化服务,直到(和除非)你问它。

  • 如果你打算用单位以支付您的服务测试 - 然后选择2 definatelly更好,因为你并不需要模拟$ EM-> getRepository()调用在测试开始。

  • 的好处个别安装人员 - 也与单元测试有关。例如,对于一个测试用例,您只需要一个依赖项,即可用于另一个测试用例 - 另一个依赖项。所以,你可以在测试中使用setter来设置mock,而且你不需要将所有的mock都传递给构造函数。

+0

我不认为这与mock有很大关系 - 你总是可以禁用构造函数,并且嘲讽3-4类依赖关系通常很简单。但这只是我的意见:) –

+3

仔细查看发布的代码。一旦服务构建完成,回购就从实体经理中撤出。没有性能差异。你关于单元测试和个人设置的第三点是真正扩展事物。这个类需要它的依赖关系,或者它不需要。如果某个类在某些时候只需要一些依赖关系,那么它可能应该被重构。 – Cerad

+0

确实,在一种情况下,您需要手动提取存储库,在另一个DI中为您执行此操作,但也仅在请求服务时才执行。答复更新,感谢指点。 –