2009-12-11 2 views
9

アプリケーションの変数に基づいて依存クラスを変更できる状況でIoCを使用する方法を理解しようとしていますケース、セッション状態)。たとえば、クライアントごとに異なるデータベースがあるため、セッションに格納された値に基づいてデータベースへの接続を構築する必要があります(複数のビジネスを所有しているユーザーがいて、 。キークラスでセッション(または他のコンテキスト固有の変数)が必要な場合にIoCを設定する方法

public class MyTestController : ControllerBase 
{ 
    Repository _rep; 

    public MyTest(Repository rep) 
    { 
     _rep = rep; 
    } 

    public MyTest() 
    { 
     string connString = String.Format("Server={0}; Database={1};" 
      , SessionContainer.ServerName, SessionContainer.DatabaseName; 
     var dc = new DataContext(connString); 
     _rep = new Repository(dc); 
    } 

    public int SampleFn() 
    { 
     return _rep.GetCountOfEmployees(); 
    } 
} 

public class Repository 
{ 
    DataContext _context; 

    public Repository(DataContext context) 
    { 
     _context = context; 
    } 
} 

は、我々は、デフォルトのC-TORSをのIoCを使ってこれを設定し、排除することができるようになります。

ここでは、現在この構造を設定したいかの一般的な例はありますか?もしそうなら、どうですか?私はD.I.を使用するだけで問題はありません。このように、私はStructureMapまたはUnityの可能性を探求したいと思います(注:通常、db/serverをdatacontextを構築するファクトリクラスに渡します。上記の例は簡潔にするためのものです)。

答えて

13

リポジトリインスタンスがどのように作成され、どのようにライフタイムが作成されるかは、コントローラの関心事ではありません。

コンテナにコンポーネントを登録するときは、コンポーネントの有効期間を指定する必要があります。実装に応じて、セッションに従うようにリポジトリのライフ・フィーを設定することもできます。

いずれの場合でも、セッションからリポジトリを作成するためにファクトリを使用できますが、コントローラの外部から行うことができます。

デフォルトのコンストラクタを削除する必要があります。私の頭の上オフ


私はUnityまたはのStructureMapでこれを行う方法を覚えているので、ここでは城ウィンザーの例だことはできません。

抽象ファクトリーを定義します。

public interface IRepositoryFactory 
{ 
    Repository Create(); 
} 

と実装

public class MyRepositoryFactory : IRepositoryFactory 
{ 
    private readonly HttpContextBase httpContext; 

    public MyRepositoryFactory(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
     { 
      throw new ArgumentNullException("httpContext"); 
     } 

     this.httpContext = httpContext; 
    } 

    #region IRepositoryFactory Members 

    public Repository Create() 
    { 
     // return Repository created from this.httpContext 
    } 

    #endregion 
} 

今私はPerWebRequestのライフスタイルを使用しますが、あなたならばしたすべてのものをここで

container.AddFacility<FactorySupportFacility>(); 
container.Register(Component.For<IRepositoryFactory>() 
    .ImplementedBy<MyRepositoryFactory>() 
    .LifeStyle.PerWebRequest); 
container.Register(Component.For<Repository>() 
    .UsingFactory((IRepositoryFactory f) => f.Create()) 
    .LifeStyle.PerWebRequest); 

を登録PerWebSessionのカスタムライフスタイルを作成したいと思うかもしれません。これは城ではあまり難しいことではありませんが、他のDIコンテナでどれくらい難しいのか覚えていません。

MyRepositoryFactoryが依存するため、HttpContextBaseも登録する必要があります。

+0

マーク - 具体的な例がありますか?複数のリポジトリオブジェクトを持つことができます。これらのオブジェクトのすべては、適切なトランザクション処理のために同じDataContextを使用する必要があります。 "DataContext"がグローバルまたはコンテナで定義された接続文字列を使用するときにIoCコンテナに登録するのに問題はありませんが、接続文字列がユーザーのセッションにあるときはどうなりますか?私は何かが明らかに欠けているように感じる。 –

+0

私の答えに例を追加しました。 –

+0

ああ、私は今それを得ると思います! =) 私は明日あなたに二重の勝利のためにアップアップすることができるようにあなたを下降させました。素晴らしい応答。 –

関連する問題