2012-10-11 34 views
10

Ben bir arabirim var şöyle IService örneklerinin,:Ninject bağlamaları

public sealed class DispatcherService : IService 
{ 
    private IEnumerable<IService> _children; 

    public DispatcherService(IEnumerable<IService> children) 
    { 
     this._children = children.ToList(); 
    } 

    public void DoStuff(int parm1, string parm2, Guid gimmeABreakItsAnExampleK) 
    { 
     foreach(var child in this._children) 
     { 
      child.DoStuff(parm1, parm2, gimmeABreakItsAnExampleK); 
     } 
    } 
} 

Ancak, şuna benzer bir döngüsel bağımlılık gösteren çalışma zamanında bir istisna atma rüzgar benim bağlamaları,:

this.Bind<IService>().To<DispatcherService>(); 

this.Bind<IService>().To<SomeOtherService>() 
    .WhenInjectedExactlyInto<DispatcherService>(); 
this.Bind<IService>().To<YetAnotherService>() 
    .WhenInjectedExactlyInto<DispatcherService>(); 

Bu mümkün mü? Eğer öyleyse, ne yapıyorum yanlış? Ninja bu döngüsel bağımlılıktan kaçabilir mi?

+0

Neden 'WhenInjectedExactlyInto', neden sadece' To' gerekiyor: basitçe kısa sizin döngüsel bağımlılığı devre arasında daha açık bir yol bu gibi görünüyor? – casperOne

+0

"WhenInjectedExactlyInto", "SomeOtherService" ve "YetAnotherService" öğelerinin, "DispatcherService" gibi bir şeye enjekte edilmesini önlediğinden. "Sarmak" için benzer bir yaklaşım kullandım (bkz. Http://stackoverflow.com/questions/6752674/dependency-injection-how-to-configure-interface-bindings-for-wrapping) Çok enjeksiyonlu kutu için çalışsın. – FMM

+0

Çeşitli Etkinlik Aracısı uzantılarına baktınız - bunların hepsi örneklerinizi büyük ölçüde yapıyor. Tamam, sadece bir örnek olduğunu söyledin, sessiz olacağım! –

cevap

2

, bu işi (ben test) yapar: When fıkra bu durum için çalışır

kernel.Bind<IService>().To<DispatcherService>().When(x => x.IsUnique); 
this.Bind<IService>().To<SomeOtherService>() 
    .WhenInjectedExactlyInto<DispatcherService>(); 
this.Bind<IService>().To<YetAnotherService>() 
    .WhenInjectedExactlyInto<DispatcherService>(); 

nedeni Yapıcınız, bir hizmetin tek bir örneğini çağırdığında, IRequest'un IsUnique alanı true olarak ayarlanmış olur. DispatcherService aktive olduğunda bir IEnumerable için DispatcherService aramalar beri değer false olduğunu. Bu, dairesel bağımlılığın olmasını engeller.

Gerçekten, çalışacak kendisi içine DispatcherService enjekte etmeye değil çekirdek anlatan herhangi doğru yolu (bu sadece bir potansiyel olarak faydalı bir örneğidir).

Düzenleme:

kernel.Bind<IService>().To<DispatcherService>().When(
    request => request.Target.Member.DeclaringType != typeof (DispatcherService)); 
+0

Teşekkürler, bayım! Cevabınızı "IRequest" in "IsUnique" bayrağıyla ilgili bazı bilgileri içerecek şekilde güncelleyebiliyorsanız, cevap ve ödül size ulaşır. – FMM

+0

@FMM Teşekkürler. Umarım açıklamam pek sakıncaz değildir :) –

+0

Mükemmel, teşekkürler! Tek örnekli ve çok örnekli bir şey karşısında, isUnique, IMHO isminden hemen belli olmaz. – FMM

1

ben Ninject API ile aşina değilim itiraf etmeliyim, ama bu hile yapacağını düşünüyorum:

kernel.Bind<IService>().To<DispatcherService>(); 

kernel.Bind<IEnumerable<IService>>().ToMethod(() => new IService[] 
{ 
    kernel.Get<SomeOtherService>(), 
    kernel.Get<YetAnotherService>(), 
}); 
+0

Çalışmıyor. Yine de çevrimsel bağımlılığa neden olur. IEnumerable 'yerine' IService [] 'kullanılmasının da bir etkisi yoktur. – FMM

+0

Üzgünüm. Sanırım nedenini anlıyorum (ama bunu Ninject'de nasıl çözeceğimi bilmiyorum). Ninject, farklı uygulamalarla '() 'adlı farklı çağrıya birden çok çağrı yapılmasına izin verir ve Ninject, koleksiyonu çözmek için hepsini kullanır.(Bu, çoğu kapların sahip olduğu bir özellik ve çok sevmediğim bir şey). Bence bu sizin elinizdeki IEnumerable 'kaydını geçersiz kılar. Sanırım hile bir “IList ” veya “IService []' kaydettirmek ve 'DispatcherService 'inizin doğrudan bu IList ' veya 'IService []' ye bağlı olmasını sağlamaktır. – Steven

0

Sen dışında iki alt kümelerini (ya Dispatcher veya alıcıları) ayırmak olabilir Bunlardan birini Adlandırılmış Bağlama yaparak ve sonra adı birini diğerine (ya da NamedAttribute aracılığıyla ya da kablolarınızda) bir yol olarak kullanın (

+0

Kod örneği? Aynı zamanda, 'DispatcherService' kurucusunun, kaçınmak istediğim Ninja özgü niteliklere ihtiyaç duyacağı gibi geliyor. – FMM

+0

Üzgünüm, bu anı çok meşgul - bir örnek olmadan sıralayamazsanız tekrar ping yapın. Adlandırılmış örnekler için wiki'ye bir göz atın ... –

1

Neden DispatcherService'den IService'den kurtulun ve arayın IDispatcherService ve çağrılan hizmetleri (alıcılar) IService uygulamak? senin memuru parametre olarak IServices listesini alacak sadece iService ise