0

しばらく私のIoCコンテナとしてUnityを使用していましたが、再発問題の正しい解決策を見つけることができませんでした。私はあなたが怒鳴る見ることができるように、操作の引数に応じて、(彼らはIAuditOperationLogWriterインタフェースを実装)AuditInsertLogWriterとAuditUpdateLogWriterのいくつかのインスタンスを作成する必要があります。Unity - コンテキストに応じて正しいインスタンスを解決する

public IAuditOperationLogWriter Create(Operation operation) 
{ 
    switch (operation) 
    { 
     case Operation.Insert: 
      return UnityContainer.Resolve<AuditInsertLogWriter>(); 
     case Operation.Update: 
      return UnityContainer.Resolve<AuditUpdateLogWriter>(); 
     default: 
      break; 
    } 
} 

事はそれらのインスタンスがあるため、独自の依存関係の作成が複雑であることです。さらに、この工場でUnityとの依存関係を取り除きたい。だから、私の質問です:どのように達成することができますUnityは、いくつかのコンテキストに応じて作成する正しいタイプを解決する?

+1

本当に問題の一般的なタイプであるものに一般的な答えは、ここを参照してください:http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created- via-a-di-container/1945023#1945023 –

答えて

3

コンテナでの工場の依存関係を削除する場合は、事前にすべての依存関係を取り除く必要があります。

これを行うための洗練された方法は、Unityが自動工場をサポートすることです。

あなたはこのようなあなたの工場を定義することができます。

public class AuditOperationLogWriterFactory 
{ 
    private Dictionary<Operation, Func<IAuditOperationLogWriter>> auditCreator = 
     new Dictionary<Operation, Func<IAuditOperationLogWriter>>(); 

    public AuditOperationLogWriterFactory(Func<AuditInsertLogWriter> insert, 
     Func<AuditUpdateLogWriter> update) 
    { 
     auditCreator[Operation.Insert] = insert; 
     auditCreator[Operation.Update] = update; 
    } 

    public IAuditOperationLogWriter Create(Operation operation) 
    { 
     if (auditCreator.ContainsKey(operation)) 
     { 
      return auditCreator[operation](); 
     } 

     return null; 
    } 
} 

そしてあなただけの工場を解決することができますし、Unityは依存関係を配線しなければならないと、オブジェクトの作成は、(コンテキストに基づいて)実行時まで延期されます。それらが複雑な場合は、設定(設定ファイル、コード、または属性)を手助けする必要があります。

IUnityContainer container = new UnityContainer(); 

var factory = container.Resolve<AuditOperationLogWriterFactory>(); 

var logWriter = factory.Create(Operation.Insert); 
+0

私はあなたのアイデアがより良く見えるものの、同様のアプローチを採用しました。私はまだこれを試していない(私はできるだけ早くそれをやろうとしている)。それがうまくいくかどうか分かりませんが、私は投票してくれます。ありがとうございます。 – lontivero

+0

すてきな解決策。私は辞書を落とすだろう。 2つの選択肢についてのみ、それはあなたに何らかのパフォーマンスを買わないでしょう。簡単なスイッチかif-then-elseは、少なくとも同じくらい速いです。 –

+0

@SebastianWeber:あなたの意見に同意します。私は[以前の](http://stackoverflow.com/revisions/8599174/1)にはif-then-elseがありましたが、それを変更しました。私はここでのパフォーマンスについて心配していませんでしたが、新しいタイプを追加したい場合は、ifステートメントまたはswitchステートメントを変更する必要はありません。 –

0

登録名を使用してタイプを登録することができます。登録名は操作名にすることができます。解決するときは、適切な名前を使用し、適切な登録を取得します。

UnityContainerのRegisterメソッドとResolveメソッドのオーバーロードリストを参照し、 'name'パラメータを持つものを探します。それはあなたが探しているものです。

+1

これは有効なアプローチですが、私の工場クラスのコンテナへの参照は必要ありません。 – lontivero

関連する問題