7

asp.net mvc3でUnityを使用するためのいくつかのチュートリアルで、このコード行を見てきました。Service Locatorはアンチパターンであり、ベストプラクティスではないという印象を受けました。このServiceLocatorは、定義されたアンチパターン以外のものですか、それともこのコード行/この実装は悪い習慣と見なされていますか?

ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
4

3 に答える 3

13

古い質問ですが、他の人の利益のために:

「サービスの場所はアンチパターンです」というマントラに完全に同意しますが、そのルールには間違いなく例外があります。

依存性注入(Unityなど)を使用する場合は、もちろん、ServiceLocatorを使用せず、すべてのサービスクラスにコンストラクター注入のみを使用してください。(また、DTOなどの値オブジェクト以外には「new」を使用しないでください。)

ただし、コンストラクターインジェクションを使用できない場合があり、サービスにアクセスする唯一の方法は、回避策を使用してUnityコンテナーに直接アクセスすることです。そのような場合、ServiceLocatorは達成するための優れた標準的な方法です。それ。これは、クラスがユーザーによってインスタンス化されていない場合(より具体的には、Unityによってインスタンス化されていない場合)ではなく、たとえば.NETFrameworkによってインスタンス化されている場合です。

ServiceLocatorが役立つ可能性のあるいくつかの簡単な例は、Unityコンテナーに登録されているサービスにアクセスする方法です。

  1. WCFIEndpointBehaviorまたはIClientMessageInspectorの実装
  2. WPFIValueConverterの実装
  3. または、必ずしもクラスから「サービス」にアクセスする必要はないかもしれませんが、ユニットテスト可能なコードを記述したいだけですが、何らかの理由でクラスをまったく(または簡単に)インスタンス化できないためです。通常は.NETFrameworkによって構築されるため、カスタムコードをテスト可能なクラスに抽出し、ServiceLocatorを使用してテスト不可能なクラスで解決します。

この行は理想的ではないことに注意してください。

ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));

ServiceLocator.Currentプロパティは、Currentにアクセスするたびに提供されるデリゲートを実行します。つまり、新しいUnityServiceLocatorが毎回作成されます。代わりに、おそらくこれを実行する必要があります。

IServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
于 2013-08-23T16:52:22.070 に答える
7

コンテナーに依存しないように設計されたフレームワークを作成する場合、サービスロケーター(アプリケーションではNo-Goである必要があります)は、Unityを別のものに交換できるようにする追加の間接層です。さらに、サービスロケーターを使用しても、そのフレームワークを使用するアプリケーションにDIを使用する必要はありません。

于 2012-02-03T06:49:03.043 に答える
2

それは人々が話しているのと同じ反パッテンです。その行が行っているのは、サービスロケータープロバイダーをUnityServiceLocatorのインスタンスに設定すること、つまりISerivceLocatorのUnity実装を使用することだけです。必要に応じて、独自の実装をIServiceLocatorにして、UnityServiceLocatorの代わりにそれを使用することもできます。

ここにリストされているように、ServiceLocatorの使用はさまざまな理由で悪い習慣と見なされています

于 2012-02-03T00:27:33.733 に答える