2012-10-11 10 views
10

मैं एक अंतरफलक है IService के उदाहरण है, तो जैसे:Ninject बाइंडिंग

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

लेकिन, मेरा बाइंडिंग, कि इस तरह दिखेगा, एक चक्रीय निर्भरता का संकेत कार्यावधि में एक अपवाद फेंक हवा:

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

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

क्या यह संभव है? यदि हां, तो मैं क्या गलत कर रहा हूँ? क्या निंजा इस चक्रीय निर्भरता विनाश से बच सकता है?

+0

आप की जरूरत क्यों है 'WhenInjectedExactlyInto', क्यों नहीं बस' To': बस कम अपने सर्कुलर निर्भरता सर्किटिंग के अधिक स्पष्ट तरीका यह प्रतीत होता है? – casperOne

+0

क्योंकि 'WhenInjectedExactlyInto'' कुछ अन्य सेवा 'और 'YetAnotherService' को' डिस्पैचर सेवा 'के अलावा किसी भी चीज़ में इंजेक्शन से रोकता है। मैंने "रैप" के लिए एक समान दृष्टिकोण का उपयोग किया है (http://stackoverflow.com/questions/6752674/dependency- इंजेक्शन-how-to-configure-interface- बाइंडिंग-for-wrapping देखें), लेकिन मैं कोशिश कर रहा हूं इसे बहु-इंजेक्शन केस के लिए काम करें। – FMM

+0

क्या आपने विभिन्न इवेंट ब्रोकर एक्सटेंशन को देखा है - वे सभी आपके उदाहरणों को बहुत गहराई से करते हैं। ठीक है, आपने कहा था कि यह सिर्फ एक उदाहरण था, मैं चुप रहूंगा! –

उत्तर

2

आपके प्रेषक ने केवल IService जो एक पैरामीटर के रूप IServices की एक सूची लेने के लिए जा रहा है, तो यह काम (मैं परीक्षण किया) करता है:

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

कारण यह है कि When खंड इस मामले के लिए काम करता है यह है कि IsUniqueIRequest का क्षेत्र true पर सेट हो जाता है जब आपका कन्स्ट्रक्टर सेवा के एक उदाहरण के लिए कॉल करता है। चूंकि DispatcherServiceIEnumerable के लिए कॉल करता है, इसलिए DispatcherService सक्रिय करते समय मान false है। यह परिपत्र निर्भरता होने से रोकता है।

वास्तव में, कर्नेल को यह कहने का कोई सही तरीका नहीं है कि डिस्पैचर सेवा को इंजेक्ट करने का प्रयास न करें (यह केवल एक संभावित उपयोगी उदाहरण है)।

संपादित करें:

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

धन्यवाद, अच्छा महोदय! यदि आप 'IRequest' के' IsUnique' ध्वज पर कुछ जानकारी शामिल करने के लिए अपना उत्तर अपडेट कर सकते हैं, तो उत्तर और बकाया आपको जाता है। – FMM

+0

@ एफएमएम धन्यवाद। मुझे उम्मीद है कि मेरी व्याख्या बहुत बेकार नहीं है :) –

+0

बढ़िया, धन्यवाद! एकल-आवृत्ति बनाम एकाधिक-आवृत्ति चीज 'IsUnique', IMHO नाम से तत्काल स्पष्ट नहीं है। – FMM

1

मैं मानता चाहिए कि मुझे लगता है कि Ninject एपीआई से परिचित नहीं हूँ, लेकिन मुझे लगता है कि इस चाल करना होगा:

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

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

काम नहीं करता है। अभी भी चक्रीय निर्भरता का कारण बनता है। 'IENumerable 'के बजाय' IService [] 'का उपयोग करने पर कोई प्रभाव नहीं पड़ता है। – FMM

+0

मुझे खेद है। मुझे लगता है कि मैं समझता हूं क्यों (लेकिन यह सुनिश्चित नहीं है कि निनजेक्ट में इसे कैसे हल किया जाए)। निनजेक्ट विभिन्न कार्यान्वयन के साथ '()' को कई कॉलों की अनुमति देता है, और निनजेक्ट संग्रह को हल करने के लिए उन सभी का उपयोग करेगा।(यह एक सुविधा है जिसमें अधिकांश कंटेनर हैं और यह ऐसा कुछ है जो मुझे बहुत पसंद नहीं है)। मुझे लगता है कि यह आपके मैनुअल 'IENumerable ' पंजीकरण को ओवरराइड करता है। मुझे लगता है कि चाल 'IList ' या 'IService []' पंजीकृत करना है और अपनी 'डिस्पैचर सेवा' इस 'IList ' या 'IService []' पर सीधे निर्भर है। – Steven

0

आप में से दो उप-समूहों (या तो डिस्पैचर या रिसीवर) को अलग कर सकता है उनमें से एक को नामित बाध्यकारी बनाकर, और फिर नाम को एक दूसरे को खिलाने के तरीके के रूप में उपयोग करें (या तो NamedAttribute या अपने तारों में)

+0

कोड उदाहरण? यह 'डिस्पैचर सेवा' कन्स्ट्रक्टर की तरह लगता है कि इसके बाद निंजा-विशिष्ट विशेषताओं की आवश्यकता होगी, जिन्हें मैं टालना चाहता हूं। – FMM

+0

क्षमा करें, इस पल में बहुत व्यस्त - फिर से पिंग करें यदि आप इसे बिना किसी उदाहरण के सॉर्ट कर सकते हैं। नामित बाइंडिंग उदाहरणों के लिए विकी पर एक नज़र डालें ... –

1

डिस्पैचर सेवा में कॉल से छुटकारा न दें और कॉल करें यह IDISpatcher सेवा है और बुलाया सेवाएं (रिसीवर) IService लागू करते हैं?