Symfony 6父控制器到子控制器的依赖注入
P粉208469050
P粉208469050 2023-08-17 20:19:03
0
1
553
<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>
P粉208469050
P粉208469050

全部回复(1)
P粉464208937

你需要的是被称为服务订阅者

在Symfony中,当控制器继承AbstractController时,它们是服务订阅者,这意味着它们被注入了一个包含一些常用服务(如twig、序列化器、表单构建器等)的小容器。

如果你想要一些你的子控制器将使用的“常见”服务,你可以通过在父控制器中重写getSubscribedServices()来扩展列表。或者如果你的控制器没有继承Symfony提供的默认控制器,你只需要实现自己的控制器:

如果你的控制器是一个服务(我猜已经是了),Symfony将使用setter注入将容器注入到你的控制器中。

代码将如下所示:

<?php

use Symfony\Contracts\Service\ServiceSubscriberInterface;


class ParentController implement ServiceSubscriberInterface {
    protected ContainerInterface $container;
    public function setContainer(ContainerInterface) { $this->container = $container; } 

    public static function getSubscribedServices() {
         // 这是静态的,所以Symfony可以在不实例化控制器的情况下“看到”所需的服务。
         // 在这里定义一些常见的服务,一个示例在Symfony的AbstractController中
    }
}

class ChildController extends ParentController {
    // 使用自定义DI来为子控制器提供服务。

    public function indexAction {
        // 你可以使用$this->container->get(...)来获取服务
    }

}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板