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注入將容器注入到你的控制器中。
程式碼將如下所示: