这似乎是使用控制器作为服务的最快捷,最简单的方法,但我仍然缺少一步,因为它不起作用。
这是我的代码:
控制器/服务:
// 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
查看服务列表时,我看不到新创建的服务。
我错过了什么?
答案 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 services和Controller 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);
}