web-dev-qa-db-ja.com

Common Service Locatorはいつ使用しますか?

私はIoCコンテナを抽象化する方法として Common Service Locator を見てきましたが、このタイプに強く反対している人がいることに気づきました。

絶対に使用しないことをお勧めしますか?いつも使ってる?または時々それを使用しますか?場合によっては、どのような状況で使用し、どのような状況で使用しないのでしょうか。

36
ajma

サードパーティの開発者が使用するライブラリコードを作成していると想像してください。コードは、これらの開発者が提供するサービスオブジェクトを作成できる必要があります。ただし、各発信者がどのIoCコンテナを使用するかはわかりません。

Common Service Locatorを使用すると、ユーザーに特定のIoCを強制することなく、上記に対処できます。

ライブラリ自体の中で、IoCに独自のクラスを登録することをお勧めしますが、発信者の邪魔にならない独自の使用のためにIoCを選択する必要があるため、今では非常に困難になっています。

32
Ian Ringrose

開発者は、このライブラリはService Locatorパターンしか実行できないと考えているため、CSLの使用に反対する議論の1つが誤っていることに気付きました。ただし、依存性注入パターンでも簡単に使用できるため、そうではありません。

ただし、CSLライブラリは、ユーザーが依存関係を登録できるようにする必要があるフレームワーク設計者向けに特別に設計されています。ライブラリはCSLを直接呼び出すため、フレームワークの観点からは、SLパターン、つまりその名前について説明します。

ただし、フレームワーク設計者として、CSLへの依存を軽視するべきではありません。フレームワークを使いやすくするために、通常は独自のDIメカニズムを使用する方がはるかに優れています。非常に一般的なメカニズムは、構成ファイルに依存関係を設定することです。このパターンは、.NETFramework全体で使用されます。ほとんどすべての依存関係を別の依存関係に置き換えることができます。 .NETプロバイダーパターンは、この上に構築されています。

フレームワーク設計者としてCSLに依存していると、ユーザーがアプリケーションを使用するのが難しくなります。ユーザーはIoCコンテナーを構成し、それをCSLに接続する必要があります。ただし、フレームワークでは、.NET構成システムを使用しているときに実行できるように構成を検証することはできません。これは、あらゆる種類の検証サポートとして使用されます。

19
Steven

最近、サービスロケーターの概念について読んだことがあります。これは結合を減らすのに役立つ方法ですが、ロケーターへのコード結合が必要です。ロケーターを支えるコンテナーではなく、ロケーター自体です。これはトレードオフですが、適切な状況では有益な場合があります。

役立つ可能性のある状況の1つは、レガシーコードなど、DIを使用しないコードがある場合です。私は今このボートに乗っています。必要なオブジェクトを直接作成するのではなく、SLを介してプルすると、抽象化を追加できます。 SLとDI/IoCの中間段階だと思います。

9
Grant Palin

サービスを必要としているライブラリコードがあり、このコードをより大きなフレームワーク/ランタイムのコンテキストでホストできる場合、フレームワーク/ランタイムは、起動時にカスタムコードを実行して初期化できるメカニズムを提供する必要がありますコンテナとレジスタの依存関係。 CSLが問題になる可能性がある良い例は、MSCRMのコンテキストでCSLを使用する場合です。 MSCRMフレームワークが特定のイベントで実行するプラグインを登録することにより、カスタムビジネスロジックを実行できます。 DIコンテナを設定するためにサブスクライブできる「スタートアップ」イベントがないため、発生する問題は、登録ロジックをどこで実行するかです。どういうわけかDIをセットアップできたとしても、プラグインからサードパーティのコードを呼び出す唯一の方法であるため、CSLとDIライブラリをGACに配置する必要があります(展開チェックリストに追加するもう1つの項目)。このようなシナリオでは、依存関係をコンストラクターパラメーターとして設定し、呼び出し元のコードが適切と判断したときに初期化できるようにすることをお勧めします(コンストラクターインジェクションまたは適切なインターフェイス実装を手動で「更新」することにより)。

0
Abhijeet Patel