2009-06-27 21 views
1

私は開発中のSDKにある内部依存関係を管理する方法を理解するのに少し問題があります。何らかの理由で、私が試したすべてのものがうまく動作しないようです。内部の依存関係の管理

が、私はこれらのクラスを持っていると言う:

class Table 
{ 
    Table(string name,IQueryProvider provider, IComObject comobject) {} 
} 

class TableFactory 
{ 
    Table BuildTable(name) <- builds a table object. 
} 

私がいる問題はBuildTable()メソッドはIQueryProviderとIComObjectを作成し、名前を下に通過しなければならないということです。 (私はそれを正しく理解していれば)私は私が望んでいるサービスロケータパターンを実装しているが、私はこのようなものを使用する場合:

BuildTable(string name) 
{ 
    IQueryProvider provider = ServiceLocator.GetInstance<IQueryProvider>(); 
    IComObject comobject = ServiceLocator.GetInstance<IComObject>(); 
    Table tab = new Table(name,provider,comobject); 
    return tab; 
} 

をそれは今私が私を作るのServiceLocatorにIQueryProviderとIComObjectの両方を持っている必要があることを意味します依存して見たりテストしたりすることは困難です。だから私は、このようなオブジェクトや工場、何かの種類を作成するために、依存関係の工場を作成しました:

class DependencyFactory 
{ 
    Table BuildTable(string name) 
    { 
     //call other BuildMethods to create objects. 
     //return new Table. 
    } 

    //Other Build methods for things like IQueryProvider, IComObject. 
} 

その後、私は私のサービスロケータでDependencyFactoryを登録してからちょうど方法を構築呼び出す必要があります。

このうちのいずれかが悪いですか?

私の最初のBuildTableメソッドは大丈夫ですか、それとも私はそれに心配していますか?

答えて

0

テストを容易にするために、依存関係注入を使用して、依存オブジェクトの作成に使用されるファクトリを提供することができます。私はすべてのタイプのオブジェクトに対して単一のファクトリでこれを好むでしょう。たとえば、テーブル用のTableFactoryがあるとします。これには2つのコンストラクタがあります。デフォルトのものは正しいファクトリをインスタンス化し、もう1つのコンストラクタは依存オブジェクトファクトリをインジェクションできるようにします。プロダクションコードでは最初のコードを使用しますが、テストでは2番目のコードを使用します。

public class TableFactory 
{ 
     private ServiceLocator Locator { get; set; } 

     public TableFactory() : this(null) { } 

     public TableFactory(ServiceLocator locator) 
     { 
      this.Locator = locator ?? new ServiceLocator(); 
     } 

     public Table BuildTable(string name) 
     { 
      IQueryProvider provider = ServiceLocator.GetInstance<IQueryProvider>(); 
      IComObject comobject = ServiceLocator.GetInstance<IComObject>(); 
      return new Table(name,provider,comobject); 
     } 
} 

ServiceLocatorクラスと似たような処理を行いますが、必要に応じてIQueryProviderとIComObjectのインスタンスを挿入します。

これは非常に簡単な注入タイプです。必要に応じて、構成ファイルを介して提供される依存オブジェクトのデフォルトバージョンを持つこともできます。その場合、デフォルトのコンストラクタのみを使用し、プロパティインジェクションを使用して依存オブジェクトを提供することができます。プロパティーは、おそらく内部の可視性を持つセッターでマークされるので、構成クラスがファクトリーを作成してプロパティーを正しく設定できるようになります。次に、InternalsVisibleToを使用してセッターをテストに利用できるようにし、そこで同じことをすることができます。

+0

それはまだ本当に見ることができないという問題を解決しません内部の依存関係。しかし、もう一度、SDKの内部にあるので、私はどのタイプが必要かを知っています。何をすべきか。 –

0

サービスロケータは、あなたが記述した理由とはまったく異なるため、アンチパターンとみなします。タイプを正しく使用する方法を理解することが非常に難しくなります。 Service Locatorの代わりにDependency Injection(DI)を使用することをお勧めします。例えば、コンストラクタインジェクション(しかし、これに限定されない)。 described in this blog postのように手動で行うこともできますし、DIコンテナで作業をさせることもできます。

一般的なDIコンテナは、以下のとおりです。

+0

可能な限りDIを使用しますが、私の主な問題は、使用するすべてのオブジェクトを作成する場所と方法です。だから、私はファクトリオブジェクトを作成しますが、そのファクトリオブジェクトはどこで作成しますか? –

+0

@Nathan W:短い答えは:必要なときです。より複雑な答えは次のとおりです。アプリケーションスタックの一番上(またはビューに応じてルート)。すべてを結ぶ場所。上記のブログ記事で説明しているように、手動で行うこともできますし、DIコンテナでそれを行うようにすることもできます。私はここでサークルを少し動かしていると思いますので、あなたの質問の次元があるかもしれません私が行方不明になっている... –

+0

私は同意します。基本的には、ルート(またはその周辺)でアプリを設定します。私はIoCが「上からのパラメトリック」と呼ばれていると聞いていますが、それはかなりです - 依存性の作成/注入は次のレベルで構成されています。 サービスロケータのパターンは、ある意味では貧しい人のDIに似ています。私は過去にそれを試して、隠された依存関係のためにコードを難しくしています。 専用のIoCコンテナを使用している場合、コードの99%はその存在を知らないままですが、アプリケーションを変更することは本当に簡単です+ configure、さらに心臓の内容まですべてをテストできます。 –

関連する問題