Symfony 6父控制器到子控制器的依赖注入
P粉208469050
2023-08-17 20:19:03
<p>我有一个基础控制器类,其中包含一些所有子控制器都会使用的实用方法。目前它有3个依赖项,但将来可能会有更多。因此,每当我想要向子控制器添加一个依赖项时,我现在遇到了一个问题,即我认为依赖注入的指令过多。</p>
<pre class="brush:php;toolbar:false;">abstract class BaseController extends AbstractController
{
public function __construct(
protected readonly SerializerInterface $serializer,
protected readonly ValidatorInterface $validator,
private readonly ResponseGenerator $responseGenerator,
) {
}
...
}
class ChildController extends BaseController
{
// 所有父类注入在所有子类中都是必需的。
public function __construct(
SerializerInterface $serializer,
ValidatorInterface $validator,
ResponseGenerator $responseGenerator,
private readonly SomeRepository $someRepository,
... 在这里插入任何其他子控制器特定的依赖项。
) {
parent::__construct($serializer, $validator, $responseGenerator);
}
...
}</pre>
<p>我尝试在基础控制器中使用<code>$this->container->get('serializer')</code>,但这不起作用,因为<code>AbstractController::$container</code>是通过注入定义的,但没有构造函数,所以无法调用<code>parent::__construct()</code>。此外,它也无法给我提供<code>validator</code>,所以即使它起作用,也只能解决部分问题。</p>
<p>我尝试寻找可以使用的属性,例如</p>
<pre class="brush:php;toolbar:false;">abstract class BaseController extends AbstractController
{
#[Inject]
protected readonly SerializerInterface $serializer;
#[Inject]
protected readonly ValidatorInterface $validator;</pre>
<p>但是没有找到类似的东西(PHP-DI有,但Symfony没有)。</p>
<p>有没有办法以某种方式消除子控制器中的重复依赖项?</p>
你需要的是被称为服务订阅者
在Symfony中,当控制器继承
AbstractController
时,它们是服务订阅者,这意味着它们被注入了一个包含一些常用服务(如twig、序列化器、表单构建器等)的小容器。如果你想要一些你的子控制器将使用的“常见”服务,你可以通过在父控制器中重写
getSubscribedServices()
来扩展列表。或者如果你的控制器没有继承Symfony提供的默认控制器,你只需要实现自己的控制器:如果你的控制器是一个服务(我猜已经是了),Symfony将使用setter注入将容器注入到你的控制器中。
代码将如下所示: