2012-02-03 12 views
5

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

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

、彼らはあまりにもMEFとのServiceLocatorを使用しています。私はそれが反パターンであったという印象を受けていたので、それをRIで見ることに驚いています。私はこれがアンチパターンと同じサービス・ロケータ・パターンの実装であると信じています。 – Lukazoid

+0

あなたはそれを後ろに持っています:例では、サービスロケータを使用しているUnityではなく、サービスロケータを介してasp.net mvc3にコードプラグを接続しています。 Service Locatorのパターンに関する討論は、宗教的な性質のものです。 asp.net mvcチームはあなたのお気に入りのDIコンテナを使用する方法を提供しなければなりませんでした。これは彼らが実装した方法です。代替案を考える。 http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx –

+0

@zespri - すべてのUnity実装でサービスロケータが使用されているわけではありませんか? –

答えて

0

これは、人々が話すのと同じ反pattenです。これらの行が行うのは、サービス・ロケータ・プロバイダをUnityServiceLocatorのインスタンスに設定することです。つまり、ISerivceLocatorのUnity実装を使用することです。必要に応じて、独自の実装をIServiceLocatorとしてUnityServiceLocatorの代わりに使用することができます。あなたは(それがアプリケーションでノー行くべきではないが)サービスロケータとらわれないコンテナなるように設計されたフレームワークを作成する場合はサービスロケータを使用して

が記載されているhere

+0

私はサービスロケータが悪い習慣であることに同意します。これが名前だけで使用されているかどうかはわかりませんでした。 –

+3

IOCコンテナを使用している場合、コンテナはどのように見つけられますか? –

+0

それは、その場所を持っています、他の答えを参照してください、それはあなたのコードを特定のDI実装に直接結びつけることから解放します。 – Alwyn

7

など、さまざまな理由のために悪い習慣と考えられていますあなたが何か別のもののためにUnityを交換することを可能にする間接の追加層です。さらに、サービス・ロケータの使用は、そのフレームワークを使用するアプリケーションに対してDIの使用を強制しません。

9

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

私は絶対に「サービスの場所は、アンチパターンである」マントラに同意する一方で、そのルールの例外は間違いなくあります。

Dependency Injection(Unityのような)を使用する場合、確かにServiceLocatorを使用せず、すべてのサービスクラスに対してコンストラクタインジェクションのみを使用します。 (また、DTOのよ​​うなバリューオブジェクト以外に "new"を使用しないでください)

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

  1. 実装やWPFのIClientMessageInspector
  2. 実装:

    のServiceLocatorは役に立つかもしれない場所のいくつかの簡単な例は、からあなたのユニティコンテナに登録されたサービスへのアクセスを得ることですIValueConverter

  3. でも、クラスから「サービス」へのアクセスを取得する必要はないかもしれませんが、単体テスト可能なコードを記述したいだけですが、なんらかの理由でクラスを全く起動できません簡単にはありません)。なぜなら、通常は.NET Frameworkによって構築されるからですカスタムコードをテスト可能なクラスに抽出し、ServiceLocatorを使用して非テストクラスで解決します。

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

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

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

私は、これはプリズムStockTrader RIに、あまりにも多くのことを見てきた使用
IServiceLocator locator = new UnityServiceLocator(container); 
ServiceLocator.SetLocatorProvider(() => locator); 
関連する問題