Symfony 2.8 自动装配方法注入

Symfony 2.8 Autowiring for method injection

Update 2020 (this should have been much sooner). There can be a new class for each controller action. Each controller can be named by the action it is going to do, with an Invoke() method. Consider "Action Domain Responder" (ADR).

Why do I want to do this? Controllers do not necessarily adhere to SRP, and I'm not about to go creating a new class for each of, what is effectively, a controller 'action'. Therefore, a controller should not have everything injected via constructor, but the relevant method being called should be able to state explicitly "I require these objects" and another method "these other objects".

As of Symfony 2.8,如果您在 services.yml.

中提供 autowire: true,则依赖注入组件现在可以为您的服务自动装配

我将控制器定义为服务,如下所示:

test_controller:
    class: AppBundle\Controller\TestController
    autowire: true

我的控制器如下所示:

class TestController
{
    public function indexAction(TestClass1 $tc1, $id)
    {
        return new Response('The slug is: ' . $id);
    }
}

您会注意到我正在为 TestClass 打字提示,这只是一个空的 class。但是,当我刷新页面时出现以下错误:

我需要在我的 services.yml 文件中更改什么才能在我的控制器方法中进行自动连接依赖注入?请注意,问题 不是 因为我之后有一个 $id 'slug'。删除它没有任何作用。

编辑:我创建了一个包,允许或多或少做你想做的事,叫做 DunglasActionBundle

免责声明:我是 Symfony 自动装配系统的作者。

Symfony 依赖注入组件(自动装配系统是其中的一部分)不是那样工作的。它只允许在服务的 class 构造函数中自动注入依赖项,而对控制器 classes、操作和 HttpKernel 组件的其他部分一无所知。

目前无法执行您想执行的操作。最初,自动装配系统是为域服务而不是控制器设计的。

应该可以使用 a custom param converter. However, I'll suggest you take another way I've first described here 桥接自动装配系统和控制器参数:

There is another approach I want to discuss since several time but I did not have the time to blog about it.

It's a derivate of/similar to the ADR pattern, applied to Symfony.

  1. An action is a single class with a __invoke() method containing all it's logic (should be only some lines of glue code to call the domain and the responder).
  2. Actions are registered as a service (it can be automated using a compiler pass and some conventions, similar to how we discover controllers right now, with the ability to override the definition if needed)
  3. On such action services, autowiring is enabled.

It means that almost as easy as current controllers to use for the developper, but with an explicit dependency graph and a better reusability. Only things that are really necessary are injected. In fact, it's already doable to use such system with Symfony. We do it in API Platform master. Here is one action for instance: https://github.com/dunglas/DunglasApiBundle/blob/master/Action/PostCollectionAction.php

In this implementation I also rely a lof on kernel events to be able to plug and play some sort of logic (persistence, validation...) in a decoupled manner but it's out of scope.