我怎样才能使用注释将控制器定义为服务?

时间:2015-07-12 08:56:19

标签: symfony service annotations

这似乎是使用控制器作为服务的最快捷,最简单的方法,但我仍然缺少一步,因为它不起作用。

这是我的代码:

控制器/服务:

// Test\TestBundle\Controller\TestController.php

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

/**
 * @Route(service="test_service")
 */
class TestController extends Controller {
  // My actions
}

使用:

// Test\TestBundle\Controller\UseController.php

// ...
public function useAction() {
  $testService = $this->get('test_service');
}

当我这样做时,我收到错误

  

您已请求不存在的服务" test_service"。

当我使用app/console container:debug查看服务列表时,我看不到新创建的服务。

我错过了什么?

3 个答案:

答案 0 :(得分:6)

来自Controller as Service in SensioFrameworkExtraBundle

  

控制器类上的@Route注释也可用于将控制器类分配给服务,以便控制器解析器通过从DI容器中取出控制器来实例化控制器,而不是调用新的PostController()本身:

/**
 * @Route(service="my_post_controller_service")
 */
class PostController
{
    // ...
}

注释中的service属性只是告诉Symfony它应该使用指定的服务,而不是使用new语句实例化控制器。它不会自行注册服务。

鉴于你的控制人:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

/**
 * @Route(service="test_service")
 */
class TestController
{
    public function myAction()
    {
    }
}

您需要将控制器实际注册为test_service id:

的服务
services:
    test_service:
        class: Test\TestBundle\Controller\TestController

这种方法的优点是,您可以通过在服务定义中指定它们来将依赖项注入构造函数中,并且不需要扩展基类Controller类。

请参阅How to define controllers as servicesController as Service in SensioFrameworkExtraBundle

答案 1 :(得分:3)

对于未来的人,如果您决定使用控制器即服务,则最好通过构造函数将服务注入控制器,而不是通过服务定位器获取服务。前者被认为是反模式,而后者允许简单的单元测试,而且更加冗长。

所以而不是:

public function useAction() {
    $testService = $this->get('test_service');
}

你应该:

private $yourService;

public function __construct(YourService $yourService)
{
    $this->yourService = $yourService;
}

public function useAction()
{
    $this->yourService->use(...);
}

不要创建快捷方式,编写可靠,可维护的代码。

答案 2 :(得分:0)

对于Symfony 3.4,我们不需要将控制器注册为服务,因为它们已经使用默认的services.yml配置注册为服务。

您只需要编写以下内容即可:

// current controller

public function myAction() {
  $test = $this->get(SomeController::class)->someAction($param);
}