古い質問が、他の利益のために:
私は絶対に「サービスの場所は、アンチパターンである」マントラに同意する一方で、そのルールの例外は間違いなくあります。
Dependency Injection(Unityのような)を使用する場合、確かにServiceLocatorを使用せず、すべてのサービスクラスに対してコンストラクタインジェクションのみを使用します。 (また、DTOのようなバリューオブジェクト以外に "new"を使用しないでください)
しかし、単にコンストラクタインジェクションを使用できない場合、サービスにアクセスする唯一の方法は次のとおりです。あなたのUnityコンテナに直接アクセスするための回避策を使用してください。そのような場合、ServiceLocatorはそれを達成するための標準的な方法です。これは、クラスがあなたによってインスタンシエートされていない(または具体的にはUnityによってインスタンス化されていない)場合ですが、たとえば.NETフレームワークによってインスタンス化されます。 WCF IEndpointBehaviorの
- 実装やWPFのIClientMessageInspector
- 実装:
のServiceLocatorは役に立つかもしれない場所のいくつかの簡単な例は、からあなたのユニティコンテナに登録されたサービスへのアクセスを得ることですIValueConverter
- でも、クラスから「サービス」へのアクセスを取得する必要はないかもしれませんが、単体テスト可能なコードを記述したいだけですが、なんらかの理由でクラスを全く起動できません簡単にはありません)。なぜなら、通常は.NET Frameworkによって構築されるからですカスタムコードをテスト可能なクラスに抽出し、ServiceLocatorを使用して非テストクラスで解決します。
この行が理想的ではないことに注意してください:
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
ServiceLocator.Currentプロパティは、デリゲートを実行しようとしているが、あなたは現在アクセスするたびに提供し、新しいUnityServiceLocatorが毎回作成されますしようとしている、すなわち、 。代わりに、あなたはおそらくこれをしたい:
私は、これはプリズムStockTrader RIに、あまりにも多くのことを見てきた使用
IServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
、彼らはあまりにもMEFとのServiceLocatorを使用しています。私はそれが反パターンであったという印象を受けていたので、それをRIで見ることに驚いています。私はこれがアンチパターンと同じサービス・ロケータ・パターンの実装であると信じています。 – Lukazoid
あなたはそれを後ろに持っています:例では、サービスロケータを使用しているUnityではなく、サービスロケータを介してasp.net mvc3にコードプラグを接続しています。 Service Locatorのパターンに関する討論は、宗教的な性質のものです。 asp.net mvcチームはあなたのお気に入りのDIコンテナを使用する方法を提供しなければなりませんでした。これは彼らが実装した方法です。代替案を考える。 http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx –
@zespri - すべてのUnity実装でサービスロケータが使用されているわけではありませんか? –