2011-01-17 8 views
6

Unityコンテナで2つのインターフェイスを操作しているときに、同じコンテナに登録されているような気がします。コード例が明確になります。Unity:2つのインターフェイスで同じタイプを登録する

私は以下のクラス階層があります。

public interface IBaseInterface 
    { 

    } 

    public interface IInterface1: IBaseInterface 
    { 

    } 
    public interface IInterface2: IBaseInterface 
    { 

    } 
    public class Interface1Impl : IInterface1 
    { 
    } 
    public class Interface2Impl : IInterface2 
    { 
    } 

    public class BaseInterfaceDecorator: IInterface1,IInterface2 
    { 
     private readonly IBaseInterface baseInterface; 

     public BaseInterfaceDecorator(IBaseInterface baseInterface) 
     { 
      this.baseInterface = baseInterface; 
     } 
    } 

    public class MyClass 
    { 
     private readonly IInterface1 interface1; 

     public MyClass(IInterface1 interface1) 
     { 
      this.interface1 = interface1; 
     }    
    } 

をそして、これは登録コードです:

var container = new UnityContainer();   
     container.RegisterType<IInterface1, BaseInterfaceDecorator>(
      new InjectionConstructor(
       new ResolvedParameter<Interface1Impl>())); 

     container.RegisterType<IInterface2, BaseInterfaceDecorator>(
      new InjectionConstructor(
       new ResolvedParameter<Interface2Impl>())); 


     var dependency = container.Resolve<MyClass>(); 

私はInterface2Impl代わりのInterface1ImplとBaseInterfaceDecoratorを得ているのMyClassを解決する場合。私には不思議そうだ。説明できますか?

答えて

9

"to"型の最後の注入命令のように見えます。 Reflectorのコピーを取得し、UnityContainer.RegisterType(型、型、文字列、LifetimeManager、InjectionMember [])の実装を見てみると、その理由がわかります。

IMO、この動作はバグです。最低限、InjectedMembers.ConfigureInjectionFor(Type、string、InjectionMember [])は、以前の注入構成を静かに置き換える代わりに例外をスローする必要があります。しかし、あなたがしようとしていることを本当にサポートしなければなりません。

+0

これは読者に明らかではありません。内部的にUnityは 'to'タイプのビルドキーをキャッシュします(例えば、ジェネリックシグネチャでは 'TTo')。次に 'TFrom'タイプを解決すると、 'TTo'のビルドキーがビルドアップを実行するために使用されます。このビルドキーは生涯のマネージャーにも関連付けられているので、UnityはTFToのアイデンティティに関係なく、TToのすべてのサブクエリの解決に最初に使用されたライフタイムマネージャー(ビルドアップ)を使用するように見えます。 これはUnityのビルドキー。この問題を回避するには、名前の付いた登録を使用します。これは、共変型IDの確立のポイントを打ち負かします。 –

2

私はそれが役立つかどうかわかりません。今はあなたにとってはおそらく遅すぎるでしょう。ただし、名前付き登録を使用すると解決できます。つまり、解決する各タイプを別の名前で登録します。例えば

:場合

Container.RegisterType<IInterface1, BaseInterfaceDecorator>("interface1"); 
Container.RegisterType<IInterface2, BaseInterfaceDecorator>("interface2"); 
+0

これは有効な回避策ですが、登録時に共変タイプを使用する目的を無効にします。 Unityは、 'TTo'のすべての解決がTToインスタンスを作成するための同じ設定/命令を参照するという前提を作ります。したがって、注入パラメータとライフタイムマネジメントでは、TFromのアイデンティティが異なる動作(異なる注入パラメータ、異なるライフタイムマネージャなど)になるべき問題があります。 –

関連する問題