古い質問ですが、他の人の利益のために:
「サービスの場所はアンチパターンです」というマントラに完全に同意しますが、そのルールには間違いなく例外があります。
依存性注入(Unityなど)を使用する場合は、もちろん、ServiceLocatorを使用せず、すべてのサービスクラスにコンストラクター注入のみを使用してください。(また、DTOなどの値オブジェクト以外には「new」を使用しないでください。)
ただし、コンストラクターインジェクションを使用できない場合があり、サービスにアクセスする唯一の方法は、回避策を使用してUnityコンテナーに直接アクセスすることです。そのような場合、ServiceLocatorは達成するための優れた標準的な方法です。それ。これは、クラスがユーザーによってインスタンス化されていない場合(より具体的には、Unityによってインスタンス化されていない場合)ではなく、たとえば.NETFrameworkによってインスタンス化されている場合です。
ServiceLocatorが役立つ可能性のあるいくつかの簡単な例は、Unityコンテナーに登録されているサービスにアクセスする方法です。
- WCFIEndpointBehaviorまたはIClientMessageInspectorの実装
- WPFIValueConverterの実装
- または、必ずしもクラスから「サービス」にアクセスする必要はないかもしれませんが、ユニットテスト可能なコードを記述したいだけですが、何らかの理由でクラスをまったく(または簡単に)インスタンス化できないためです。通常は.NETFrameworkによって構築されるため、カスタムコードをテスト可能なクラスに抽出し、ServiceLocatorを使用してテスト不可能なクラスで解決します。
この行は理想的ではないことに注意してください。
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
ServiceLocator.Currentプロパティは、Currentにアクセスするたびに提供されるデリゲートを実行します。つまり、新しいUnityServiceLocatorが毎回作成されます。代わりに、おそらくこれを実行する必要があります。
IServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);