Symfony 6 の親コントローラーから子コントローラーへの依存関係の注入
P粉208469050
2023-08-17 20:19:03
<p>すべての子コントローラーが使用するいくつかのユーティリティ メソッドを含む基本コントローラー クラスがあります。現在、依存関係は 3 つありますが、将来的にはさらに依存関係が増える可能性があります。そのため、子コントローラーに依存関係を追加したいときは常に、依存関係注入のディレクティブが多すぎると思われる問題が発生します。 </p>
<pre class="brush:php;toolbar:false;">抽象クラス BaseController は AbstractController を拡張します
{
パブリック関数 __construct(
protected readonly SerializerInterface $serializer,
protected readonly ValidatorInterface $validator,
プライベート読み取り専用 ResponseGenerator $responseGenerator,
) {
}
...
}
クラス ChildController は BaseController を拡張します
{
// すべての親クラスのインジェクションはすべての子クラスで必要です。
パブリック関数 __construct(
SerializerInterface $serializer,
ValidatorInterface $validator,
レスポンスジェネレーター $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;">抽象クラス BaseController は AbstractController を拡張します
{
#[注入]
protected readonly SerializerInterface $serializer;
#[注入]
protected readonly ValidatorInterface $validator;</pre>
<p>しかし、同様のものは見つかりませんでした (PHP-DI にはありますが、Symfony にはありません)。 </p>
<p>子コントローラーの重複した依存関係を何とか排除する方法はありますか? </p>
あなたに必要なのは、サービス サブスクライバーと呼ばれることです
Symfony では、コントローラーが
AbstractController
を継承すると、コントローラーはサービス サブスクライバーになります。これは、コントローラーに、いくつかの共通サービス (twig、シリアライザー、フォーム ビルダーなど) の小さなコンテナーを含むライブラリが注入されることを意味します。子コントローラーが使用する「共通」サービスが必要な場合は、親コントローラーの
getSubscribedServices()
をオーバーライドしてリストを拡張できます。または、コントローラーが Symfony が提供するデフォルトのコントローラーを継承していない場合は、独自のコントローラーを実装する必要があります:コントローラーがサービスである場合 (すでにそうなっていると思います)、Symfony はセッター注入を使用してコンテナーをコントローラーに注入します。
コードは次のようになります:
リーリー