Symfony 2: 控制器的依赖注入(DI)

13

有没有可能通过纯构造函数依赖注入而不是在控制器内使用服务容器来使控制器依赖于它们的服务?

我想以这种方式编写控制器:

<?php

class ArticleController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
    private $articleFacade;
    private $articleRepository;

    public function __construct(ArticleFacade $articleFacade, ArticleRepository $articleRepository)
    {
        $this->articleFacade = $articleFacade;
        $this->articleRepository = $articleRepository;
    }

    public function indexAction()
    {
        ...
    }

}

不幸的是,我发现Symfony的ControllerResolver并不是通过ServiceContainer来创建控制器的新实例,而是通过简单的return new $controller调用。

1个回答

12

实际上,这是建议的做法,如果你看大多数第三方捆绑包,例如FOSUser,你可以看到它们确实是这样做的。

诀窍在于将您的控制器定义为服务,然后使用服务ID而不是类名。

http://symfony.com/doc/current/cookbook/controller/service.html

请记住,您将不得不注入所有所需的服务,例如实体管理器,并且通常不会扩展Symfony基类。当然,你可以注入完整的容器,但这往往被认为是不好的做法。


1
看一下我的AbstractControllerBundle。 它的目的是为您提供一个父服务,以简化使用控制器作为服务。 - Elnur Abdurrakhimov
9
FOSUserBundle好像没有这个功能?我理解得对吗?Václav的问题是关于通过构造函数注入它们,而FOSUserBundle使用的是$this->container->get('service'); https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/RegistrationController.php - Steve
根据官方文档,“将控制器定义为服务并不是Symfony的官方推荐做法”,实际上这样做是不被推荐的。 - rybo111
@rybo111 确实,但当我在5年前写下这个答案时,Symfony最佳实践文档还不存在。如果你看一下依赖注入与服务定位器的辩论,那么依赖注入通常会胜出。但今天有趣和相关的是,Symfony 4默认将控制器定义为服务。轮子转动。 - Cerad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接