2012-07-26 19 views
7

aşağıdaki sınıfları:Ninject birden

using System; 

interface IA { } 

class A1 : IA { } 

class A2 : IA { } 

class B 
{ 
    public B(IA a) {} 
} 

class BProvider : Provider<B> 
{ 
    IA _a; 

    public BProvider(IA a) { _a=a; } 

    protected override B CreateInstance(IContext context) { return new B(_a); } 
} 

Ninject modül Yük() kodu:

Bind<IA>().To<A1>(); 
Bind<IA>().To<A2>(); 
Bind<B>().ToProvider<BProvider>(); 

ana kod:

kernel.GetAll<IA>(); // works fine 
kernel.GetAll<B>(); // I expect to get IEnumerable<B> with two elements, but instead of this I get an error that there are multiple bindings of IA and ninject cannot determine which to use 

Yani soru Son ifadeyi beklediğim gibi yapabilir veya başka bir şekilde yapabilir miyim?

cevap

2

Bu istisnayı atar; çünkü Ninject, BProvider türünde bir nesne örneği oluşturması gerekir. Bunu yapmak için, IA bağımlılığını doldurmak zorundadır. Ama an ... IA'da hangisini seçmeliyim diye iki bağ var mı?

Hangi uygulamanın kullanılması gerektiğine karar vermek için bazı koşullu bağlamaları kullanabilirsiniz. bir yolu NamedAttribute ile: A1 NamedAttribute belirtilmemişse varsayılan olarak enjekte edilecek bu durumda

Bind<IA>().To<A1>(); 
Bind<IA>().To<A2>().Named("SecondImpl"); 
Bind<B>().ToProvider<BProvider>(); 


class BProvider : Provider<B> 
{ 
    IA _a; 

    public BProvider([Named("SecondImpl")]IA a) { _a=a; } 

    protected override B CreateInstance(IContext context) { return new B(_a); } 
} 

.

veya @Remo Gloor gibi

bu yazı açıklıyor: Bu biraz temizleyici Configuring Ninject

Bind<IA>().To<A1>(); 
Bind<IA>().To<A2>().WhenParentNamed("NeedSecondImpl"); 
Bind<B>().ToProvider<BProvider>().Named("NeedSecondImpl"); 

, sen Ninject için kodunuzu kravat yok ve sadece (tek bir yerde) yapılandırmasına let it çünkü.