Symfony 4服务依赖注入-构造函数与方法

墨菲

因此,我有一个Symfony控制器,并且正在通过params将所需的服务注入到我的方法中。

MySqlGroupDAO $groupDAO该控制器类的所有方法都使用params()之一。

目前,我正在将“ common”参数作为我在每种方法中的最后一个参数,例如:

/**
 * @Route("/{id}", methods={"POST"})
 * @IsGranted("EDIT_GROUP", subject="parentGroup")
 */
public function addGroup(Request $request, MySqlGroupDAO $groupDAO)  {
    $group = new Group();
    //code to init group from request

    $groupDAO->addGroup($group);

    return new Response("Adding $groupName");
}

这样做可以消除我的__construct方法。但是,我不确定这是否是最好的解决方法。由于所有方法都通用,因此最好重新添加构造函数并执行以下操作:

private $groupDAO;

public function __construct(
    Config $config,
    ValidatorInterface $validator,
    TranslatorInterface $translator,
    RequestStack $requestStack
) {
    parent::__construct($config, $validator, $translator, $requestStack);
    $this->groupDAO = new MySqlGroupDAO($config);
}


/**
 * @Route("/{id}", methods={"POST"})
 * @IsGranted("EDIT_GROUP", subject="parentGroup")
 */
public function addGroup(Request $request)  {
    $group = new Group();
    //code to init group from request

    $this->groupDAO->addGroup($group);

    return new Response("Adding $groupName");
}

这样,我消除了所有方法(在此特定类中)的大约六个参数。但是我要重新添加我的构造函数,这需要我添加一个类参数,并在构造函数中注入几个其他的参数,因为它扩展了另一个类。

与另一种方式相比,这样做有什么好处吗?

谢谢。

尼古拉斯·B

在控制器的路由方法中使用DI的原因:

  • 不易更改parent::__construct方法。在构造函数上使用DI意味着每次更改时都必须调整代码。还要注意,某些Symfony捆绑软件可能会假定控制器具有特定的签名,如果没有,可能会使您的事情变得更复杂。
  • 如果至少一条路由不使用服务,则通过使用这些细粒度的DI,我们避免在不需要时实例化服务(如果它具有自己的DI且未在其他地方使用过,则可能会非常昂贵) 。不过,这可以通过使用懒惰服务来抵消

在构造器中使用DI的原因:

  • 在控制器以外的服务(以及控制器的路由方法以外的方法,如果有的话)中,不能使用自动装配。如果要使用方法的参数注入依赖项,则必须在每次调用时手动传递该依赖项。反过来,这意味着无论哪个服务调用该方法,其本身都应在所需服务上具有DI。因此,该问题已转移,但不能以这种方式无限转移,并且在某个时候,您将要在父级上使用一些自动装配。

在构造函数中使用DI的替代方法:

您还可以使用setter注入以此方式配置服务这在功能上与在构造函数中使用DI十分相似,但是它绕过了主要缺点,即与父代生成不同的签名,并且如果父代构造函数发生更改,则需要进行更多工作。

您还可以使其更易于用于经常注入的服务。使需要此DI的服务实现一个接口,并使用_instanceof对其进行配置Symfony使用它来做到这一点,ContainerAwareInterface甚至ContainerAwareTrait以声明setter和属性的形式提供了一个促进者。对于您的情况,如果有多个服务需要该MySqlGroupDAO服务,则可以定义MySqlGroupDAOAwareTraitMySqlGroupDAOAwareInterfaceMySqlGroupDAOAwareInterface在您services.yaml_instanceof部分中添加一个条目,并使用trait并在需要DI的服务中实现接口。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章