如何减少Symfony2服务中的参数数量?

时间:2016-01-29 17:34:05

标签: symfony

我正在为我的应用程序构建invoiceManager。它本质上是我的Invoice实体的模型。

我将它用作服务。

问题是我觉得__construct需要太多的论据。

现在就是这样:

function __construct($invoiceRepo, $clientRepo, $em, $templating) {
   $this->invoiceRepo = $invoiceRepo;
   $this->clientRepo  = $clientRepo;
   $this->em          = $em;
   $this->templating  = $templating;
}

问题是我现在需要访问一些YML参数,我找到的解决方案是在构造函数中添加第五个参数。

我觉得这不是正确的做法,但我找不到合适的解决方案来建立更苗条的服务。

你会怎么做?什么是最佳实践?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

有很多方法可以实现这个目标

1)您可以只注入实体管理器,然后在构造函数中获取存储库。并摆脱2个参数($ clientRepo,$ invoiceRepo)。像这样:

__construct( $em, $templating) {
      $invoiceRepo = $em->getRepository('InvoiceRepo');
      $clientRepo = $em->getRepository('ClientRepo);
      // ...
}

2)您可以通过setter注入服务并减少构造函数参数的数量

services.yml

中的

    my.service:
     class: AppBundle\Manager\MyManager
      arguments: [@doctrine.orm.entity_manager]
      calls:
        - [setMyService1, [@my.service1] ]
        - [setMyService2, [@my.service2] ]
AppBundle\Manager\MyManager

中的

// ...
public function setMyService1($service) {
   $this->myService1 = $service;
}

public function setMyService1($service) {
   $this->myService1 = $service;
}

// ...

我不建议将整个容器注入服务中。除了其他原因,这种做法使得课程不太可测试。

答案 1 :(得分:0)

您自己的服务系统中的许多其他服务由于多种原因而不是问题:

  • 容器识别正在实现使用依赖注入,使用单例模式作为服务实例
  • 您也不会在服务中使用参数服务,性能应用程序不会降级,因为该服务已经确定已经实现
  • 许多服务使用许多服务。对于所有这些服务,symfony不会为每个服务创建所有这些参数作为实例。 SF共享同一服务的所有呼叫

一个好的,最简单的做法是使用能够启动所需的所有其他服务的容器(如@malcolm)

但(也许)

您可以查看代码的结构,以链接您的责任,而不是切入极端原子功能。

服务需要服务B需要服务C

取代

服务A AND服务B和服务C在同一个其他服务中。

最后,这只是一个不同的反思,没有必要总是在服务中实现所有逻辑。 好的服务是很好的做法 Ok控制器更小是好的 但是,所有用于表现良好并尊重良好实践的逻辑并不是一种好的做法。

优化是一项非常困难且广泛的讨论。如果存在一个在任何地方随时都可以运行的独特解决方案,那么所有开发人员都知道并且没有必要进行讨论......您必须平衡您对所有这些实践的反思并进行测试。