2011-01-17 13 views
6

İki arabirim ile çalışırken, her ikisi de aynı dekoratöre kayıt olan Unity kapsayıcısında tuhaf bir davranış görüyorum. Bir kod örneği daha açık olacaktır. Unity: Aynı tür iki arabirim için kaydediliyor

Ben aşağıdaki sınıf hiyerarşisi vardır:

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; 
     }    
    } 

Ve bu kayıt kodu:

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>(); 

Ben Interface2Impl yerine Interface1Impl ile BaseInterfaceDecorator alıyorum Sınıfım çözme. Bana garip görünüyor. Açıklayabilir misin?

cevap

9

Verilen "to" tipi kazançlar için son enjeksiyon talimatı gibi görünüyor. Bir kopyasını Reflector kapar ve UnityContainer.RegisterType (Tür, Tür, dize, LifetimeManager, InjectionMember []) uygulamasına bir göz atın, nedenini göreceksiniz.

IMO, bu davranış bir hatadır. En azından Enjekte EdilmişMembers.ConfigureInjectionFor (Type, string, InjectionMember []), önceki enjeksiyon yapılandırmasını sessizce değiştirmek yerine bir istisna atmalıdır. Ancak, gerçekten ne denediğinizi desteklemelisiniz.

+0

; Dahili Birlik, 'to' yazısının Oluşturma Anahtarını önbelleğe alır (örn. Genel imzalarda 'TTo'). Bir sonraki 'TFrom' türünü çözdüğünüzde, 'TTo için Oluşturma Anahtarı', oluşturma işlemini gerçekleştirmek için kullanılır. Bu yapı anahtarı ayrıca bir ömür boyu yönetici ile ilişkilendirilir ve bu nedenle Unity, TTo için tüm alt düzey çözümlemeler için (Build Up'da) ilk defa kullanılan (TFrom'un kimliğine bakılmaksızın) yöneticiyi kullanır. Bu, Unity'nin bir hatasıdır. Anahtarlar oluşturun. Bu geçici çözüm, kovaryant tipi kimlikleri estabilishing noktayı yenen adlandırılmış kayıtları kullanmaktır. –

2

Yardımcı olup olmadığını bilmiyorum. Şimdilik senin için çok geç oldu. Ancak, eğer adlandırılmış kayıt kullanırsanız, yani, çözülecek her türün farklı bir adla kaydedilmesini sağlayabilirsiniz. Örneğin

:

bu okuyuculara açık değildir durumda
Container.RegisterType<IInterface1, BaseInterfaceDecorator>("interface1"); 
Container.RegisterType<IInterface2, BaseInterfaceDecorator>("interface2"); 
+0

Bu geçerli bir geçici çözümdür, ancak kayıt sırasında eşdeğer türleri kullanma amacını ortadan kaldırır. Birlik, 'TTo' için tüm çözümlerin TTo örneğinin oluşturulmasıyla aynı yapılandırma/talimatlara başvurduğu varsayımını yapar. Böylelikle, TFrom'un kimliğinin farklı davranışlarla sonuçlanması gereken Enjeksiyon Parametreleri ve Ömür Boyu Yönetimi ile ilgili sorunları göreceksiniz (farklı enjeksiyon bölmeleri, farklı ömür boyu müdürler, vs.) –