2011-09-17 18 views
6

मुझे लगता है कि मुझे कुछ स्पष्ट याद आ रही है। मैंने यहां कई संबंधित प्रश्न पढ़े हैं और मैंने निनजेक्ट की विकी पर अद्यतन प्रासंगिक बाइंडिंग पेज पढ़ा है, लेकिन यह अभी भी काम नहीं करता है।एक्सटेंशन इंजेक्शन के साथ इंजेक्शन बाध्यकारी

मैं एक विरासत अनुप्रयोग को फिर से निकालने की कोशिश कर रहा हूं जो निनजेक्ट का उपयोग करने के लिए फैक्ट्री पैटर्न का उपयोग करता है।

मेरे पास 2 कक्षाओं (कक्षा बी और कक्षासी) द्वारा लागू 1 इंटरफ़ेस (IInterface) है। IInterface एक लोड विधि है। कक्षाबी की लोड विधि में यह क्लाससी को तुरंत चालू करता है और उसके बाद इसकी लोड विधि निष्पादित करता है।

मूल रूप से प्रोग्राम प्रवाह क्लास क्लास बी बनाता है और लोड विधि निष्पादित करता है। लोड विधि में क्लासबी क्लाससी बनाता है जो कुछ काम करता है।

मेरे बाइंडिंग सेटअप के रूप में तो रहे हैं ...

Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>(); 
Bind<IInterface>().To<ClassB>().WhenInjectedInto<ClassA>(); 

जब यह यह इस त्रुटि के साथ ClassB लोड विधि में विफल रहता है चलाता है ...

त्रुटि को सक्रिय करने IInterface कोई मिलती-जुलती बाइंडिंग उपलब्ध हैं, और प्रकार आत्मनिर्भर नहीं है।

अगर मैं निम्नलिखित की कोशिश ...

Bind<IInterface>().To<ClassC>().WhenInjectedInto<ClassB>(); 
Bind<IInterface>().To<ClassB>(); 

यह एक अंतहीन लूप करता है और ClassC बनाता है कभी नहीं।

संपादित मैं एक इकाई परीक्षण है कि गुजरता है लेकिन मेरे परिणाम मैं चाहता हूँ नहीं देता में इस सरल है ...

[TestClass] 
public class NinjectTestFixture 
{ 
    private interface IDoSomething 
    { 
     void SaySomething(); 
    } 

    private class ClassA : IDoSomething 
    { 
     public void SaySomething() 
     { 
      Console.WriteLine("Hello from Class A"); 
     } 
    } 

    private class ClassB : IDoSomething 
    { 
     private IKernel _Kernel; 

     public ClassB(IKernel kernel) 
     { 
      _Kernel = kernel; 
     } 

     public void SaySomething() 
     { 
      Console.WriteLine("Hello from Class B"); 

      var x = _Kernel.Get<IDoSomething>(); 

      x.SaySomething(); 
     } 
    } 

    private class ClassC 
    { 
     private IKernel _Kernel; 

     public ClassC(IKernel kernel) 
     { 
      _Kernel = kernel; 
     } 

     public void SaySomething() 
     { 
      Console.WriteLine("Hello from Class C"); 

      var x = _Kernel.Get<IDoSomething>(); 

      x.SaySomething(); 
     } 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
     var kernel = new StandardKernel(); 

     kernel.Bind<IDoSomething>().To<ClassA>(); 
     kernel.Bind<IDoSomething>().To<ClassB>().WhenInjectedInto<ClassC>(); 
     kernel.Bind<ClassC>().ToSelf(); 

     var x = kernel.Get<ClassC>(); 

     x.SaySomething(); 
    } 

उत्पादन होता है: कक्षा सी से हैलो हैलो क्लास ए से

लेकिन मैं चाहता हूँ: कक्षा बी से कक्षा सी नमस्कार नमस्कार नमस्कार कक्षा से एक

धन्यवाद

उत्तर

6

आप नहीं ClassC में इंजेक्शन कर रहे हैं। आप कर्नेल में गुजर रहे हैं और आईडीओ को कुछ हल कर रहे हैं। एक बड़ा अंतर है।

कर्नेल को पैरामीटर के रूप में पास न करें - ऐसा करने पर निर्भरता इंजेक्शन नहीं है, यह सेवा स्थान (अंतर पर अच्छा लेख है: Service Locator is an Anti-Pattern)।

ClassC बदलें होने के लिए:

private class ClassC  
{   
    private IDoSomething _doSomething;   
    public ClassC(IDoSomething doSomething) 
    {    
     _doSomething = doSomething;   
    }   

    public void SaySomething()   
    {    
     Console.WriteLine("Hello from Class C");    
     //var x = _Kernel.Get<IDoSomething>();    
     _doSomething.SaySomething();   
    }  
} 

तुम भी (प्रकार/इंटरफ़ेस आप हल हो चाहते हैं, नहीं गिरी पारित) ClassA और ClassB के लिए एक ही परिवर्तन करने चाहिए।

+0

मैं समझता हूं कि आप क्या कह रहे हैं लेकिन विधि में कहें कुछ मुझे कुछ काम करने के लिए किसी ऑब्जेक्ट को तुरंत चालू करने की आवश्यकता है। उसी वर्ग में अन्य विधियां हैं जो अधिक काम करने के तरीकों को तुरंत चालू करती हैं। अगर मैंने ऐसा सुझाव दिया जो आप सुझाव दे रहे हैं तो मेरे कन्स्ट्रक्टर में लगभग 20 पैरामीटर होंगे। कोड मूल रूप से 6 साल पहले लिखा गया था इसलिए मैं धीरे-धीरे DI के साथ इसे फिर से निकालने की कोशिश कर रहा हूं।मैंने अपने दिमाग को रैक किया है कि यह कैसे करें और कर्नेल को गुजरना सबसे आसान समाधान था जो सबसे ज्यादा समझ में आया। मैंने एक सेवा स्थान देखा और यह वर्तमान कोड आधार को समझ में नहीं आया। – oliwa

+0

आप उत्तर सही है। जब मैंने आपके द्वारा प्रस्तावित परिवर्तन किए, तो मुझे अपेक्षित परिणाम मिल गए। – oliwa

+0

मुझे तुम्हारा क्या मतलब है - मैंने भी सिस्टम को दोबारा शुरू किया है जहां मुझे DI को पेश करने के लिए कुछ अजीब/बदसूरत अंतरिम चरणों का उपयोग करना पड़ा। –

संबंधित मुद्दे