所以我有一个Symfony控制器,并且正在通过参数将所需的服务注入到我的方法中。
此控制器类的所有方法都使用一种参数(MySqlGroupDAO $groupDAO
)。
目前,我正在将“ 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");
}
这样做,我消除了所有方法(在此特定类中)的六个参数。但是我要重新添加构造函数,这需要我添加一个类参数,并在其构造函数中注入几个其他参数,因为它扩展了另一个类。
一种方法相对于另一种方法有优势吗?
谢谢。
答案 0 :(得分:4)
导致在控制器的路由方法中使用DI的原因:
parent::__construct
方法更改的影响。在构造函数上使用DI意味着每次更改时都必须调整代码。还请注意,某些Symfony捆绑包可能会假定控制器具有特定的签名,如果没有,则可能会使您的事情变得更复杂。在构造器中使用DI的原因:
在构造函数中使用DI的替代方法:
您还可以使用setter injection并配置服务this way。这在功能上与在构造函数中使用DI十分相似,但是它绕过了主要缺点,即与父代生成不同的签名,并且如果父代构造函数发生更改,则需要进行更多的维护工作。
您还可以使其更易于用于经常注入的服务。使需要此DI的服务实现一个接口,并使用_instanceof对其进行配置。 Symfony使用其ContainerAwareInterface
来做到这一点,甚至以ContainerAwareTrait
的形式提供了一个促进者来声明setter和属性。在您的情况下,如果几个服务需要MySqlGroupDAO
服务,则可以定义MySqlGroupDAOAwareTrait
和MySqlGroupDAOAwareInterface
,并在MySqlGroupDAOAwareInterface
的{ {1}}部分,并使用trait并在需要DI的服务中实现接口。