2011-04-06 11 views
7

की तुलना में बेहतर हो सकता है यह सवाल Why do I need an IoC container as opposed to straightforward DI code?फिर भी समझने में मदद क्यों Ninject मैनुअल डि

मैं Ninject सीखने किया गया है और निम्न उदाहरण के साथ आया करने के लिए एक विस्तार है की जरूरत है, उदाहरण के ऐसा करने का मैनुअल तरीका माध्यम से चला जाता DI और

class Program 
{ 
    static void Main(string[] args) 
    { 
     NinjectWay(); 
     ManualWay(); 
     Console.ReadKey(); 
    } 

    private static void ManualWay() 
    { 
     Console.WriteLine("ManualWay***********************"); 
     IWeapon sword = new Sword(); 
     Samurai samurai = new Samurai(sword); 

     Console.WriteLine(samurai.Attack("ManualWay...")); 

     // change weapon 
     IWeapon dagger = new Dagger(); 
     samurai.Weapon = dagger; 

     Console.WriteLine(samurai.Attack("ManualWay...")); 

     IWeapon weapon = new Shuriken(); 
     IWarrior ninja = new Ninja(weapon); 
     Console.WriteLine("Manual way.. inject shuriken when a ninja. " + ninja.Weapon.Name); 

     IWarrior ninja2 = new Ninja(weapon); 
    } 

    private static void NinjectWay() 
    { 
     Console.WriteLine("NinjectWay***********************"); 
     IKernel kernel = new StandardKernel(); 
     kernel.Bind<IWeapon>().To<Sword>(); 
     var samurai = kernel.Get<Samurai>(); 

     Console.WriteLine(samurai.Attack("NinjectWay...")); 

     kernel.Rebind<IWeapon>().To<Dagger>(); 
     samurai = kernel.Get<Samurai>(); 

     Console.WriteLine(samurai.Attack("NinjectWay...")); 

     kernel.Bind<IWeapon>().To<Shuriken>().WhenInjectedInto<Ninja>(); 
     var ninja = kernel.Get<Ninja>(); 
     ninja.OffHandWeapon = new ShortSword(); 

     Console.WriteLine("Conditional Injection..."+ninja.Weapon.Name); 
     Console.WriteLine("Conditional Injection: OffhandWeapon = " + ninja.OffHandWeapon.Name); 

     var ninja2 = kernel.Get<Ninja>(); 
     Console.WriteLine("Conditional Injection..." + ninja2.Weapon.Name); 
     Console.WriteLine("Conditional Injection: OffhandWeapon = " + ninja2.OffHandWeapon.Name); 

     Console.WriteLine(""); 
    } 
} 

मुझे लगता है कि जब परियोजना का स्तर बढ़ता है तो मैं लाभ सुनता हूं लेकिन मैं इसे नहीं देख रहा हूं। इसे बेहतर समझने में मेरी सहायता करें। सी #/निनजेक्ट में और उदाहरण प्रदान करें और मुझे यह समझने में सहायता करें कि लाभ वास्तव में कहां स्पष्ट हो जाते हैं।

उत्तर

5

अन्य उत्तरों के विपरीत सुझाव है कि निनजेक मुख्य रूप से आपके कोड को अधिक टेस्ट करने योग्य नहीं बना रहा है। यह निर्भरता इंजेक्शन है जो आपके कोड को अधिक टेस्टेबल बनाता है! निर्भरता इंजेक्शन का उपयोग आईओसी कंटेनर के बिना फोकोट्री में सबकुछ बनाकर किया जा सकता है। लेकिन निश्चित रूप से, एकीकरण टेस्ट (इकाई परीक्षणों में निनजेक्ट का उपयोग न करें) के लिए आसानी से कुछ भागों को प्रतिस्थापित करने में सक्षम मधुमक्खी एक अच्छा साइड इफेक्ट है।

निनजेक्ट जैसे आईओसी कंटेनर मुख्य रूप से एक साथ काम करने वाले सॉफ्टवेयर में अपने वर्गों को रखने के बारे में हैं। छोटी परियोजनाओं में यह कुछ कारखानों का उपयोग करके आसानी से किया जा सकता है। लेकिन जैसे ही आपका आवेदन बढ़ता है कारखानों को और अधिक जटिल हो जाता है। कल्पना करें कि एक ऐसे एप्लिकेशन की कल्पना करें जिसमें विभिन्न सेवाओं की पुन: उपयोग की जा रही है, दूसरों को हर उपयोग के लिए नव निर्मित किया गया है। कुछ सेवाओं का उपयोग कई घटकों द्वारा भी किया जाता है।

यदि आप एक आईओसी कंटेनर का उपयोग कर रहे हैं तो आपको को एक बार परिभाषित करना होगा कि आपको सेवा उदाहरण कैसे मिलता है और इसकी जीवनशैली क्या होती है। दूसरी तरफ कारखाने में आपको यह निर्दिष्ट करना होगा कि आपको प्रत्येक कक्षा के लिए उदाहरण कैसे मिलता है, जिसके लिए एक उदाहरण की आवश्यकता होती है (उदा। नया MyServiceFactory()। CreateInstance())। इसके अलावा, आपको जीवन चक्र को मैन्युअल रूप से नियंत्रित करना होगा।

इसका मतलब है कि प्रोजेक्ट आकार के साथ एक आईओसी कंटेनर की कॉन्फ़िगरेशन बढ़ता है। लेकिन दूसरी तरफ एक कारखाना अधिक एक्सपोनेंशियल बढ़ता है जैसे कि ऐसी सेवाएं हैं जिनका उपयोग पूरे एप्लिकेशन में किया जाता है (जैसे उपयोगकर्ता ऑथ)।

बीटीडब्ल्यू: आपका उदाहरण बहुत अच्छा नहीं है क्योंकि रीबाइंडिंग एक आम कार्रवाई नहीं है। आमतौर पर कॉन्फ़िगरेशन केवल एक बार स्टार्टअप पर किया जाता है।

0

एक लाभ परीक्षण में आता है।

आप अपने उत्पादन कोड में तलवार से IWeapon और अपने टेस्ट असेंबली में FakeSword से IWeapon को बाध्य कर सकते हैं। यह तब उपयोगी होता है जब आपको किसी ऐसे परीक्षण की आवश्यकता होती है जिस पर IWeapon पर निर्भरता हो लेकिन आप वास्तव में असली तलवार नहीं चाहते हैं।

उदाहरण के लिए, तलवार और IWeapon के बजाय आपके पास IDataContext और DataContext है। जब आपको डीबी से कनेक्ट करने की आवश्यकता होती है तो आपके उत्पादन कोड में बढ़िया। लेकिन यूनिट परीक्षणों के लिए आप संभवतः विभिन्न कारणों (प्रदर्शन, असंगत डेटा इत्यादि) के लिए डेटाबेस को हिट नहीं करना चाहते हैं, इसलिए आप अपने IDataContext में FakeDataContext को तारित करेंगे। अब परीक्षण के लिए डीबी गतिविधि अनुकरण करने के लिए आपके पास कुछ नियंत्रण है।

0

बढ़िया प्रश्न!

बिग बिग जीत आईएमएचओ तब होता है जब आपका कोड तत्काल मांगता है, यह नहीं जानता कि वास्तविक कार्यान्वयन क्या है या नहीं। यह मजाक करने में सबसे स्पष्ट है - आपका मॉकिंग फ्रेमवर्क मजाकिया निंजा, तलवार और समाराई लौटने के लिए निनजेक्ट को कॉन्फ़िगर कर सकता है जो पूरी तरह से अलग-अलग तरीकों से आपकी अपेक्षा को लागू करता है।

मेरे पास एक रिपोजिट्री परत है, उदाहरण के लिए, आईओसी पर डेटा स्टोर तक पहुंच प्राप्त करने पर निर्भर करता है। परीक्षण के लिए, वह डेटा स्टोर वस्तुओं का एक हाथ से निर्मित संग्रह है। दूरस्थ पहुंच के लिए, डेटा स्टोर वेब सेवाओं का उपभोग करता है। स्थानीय रूप से, यह एसक्यूएल है। भंडार बस आईओसी से आईडीटास्टोर के लिए पूछता है और जो भी सेवा करने के लिए कॉन्फ़िगर किया गया हो जाता है।

क्या इससे मदद मिलती है?

0

मुख्य लाभ निनजेक्ट ने इसे मैन्युअल रूप से करने से अधिक है कि किसी और ने आपके लिए बहुत कुछ किया है। स्पष्ट रूप से आप इसी तरह के कोड को निनजेक्ट (इंटरफ़ेस प्रकारों के आधार पर ऑब्जेक्ट्स बनाने के लिए कुछ) लिखकर इसी तरह की चीज को पुन: पेश कर सकते हैं, जिससे आप अपने ऑब्जेक्ट लॉजिक से अपने ऑब्जेक्ट निर्माण को अलग कर सकते हैं लेकिन निनजेक्ट (और अन्य पुस्तकालय) सभी तैयार हैं आपके लिए कड़ी मेहनत बहुत है जब तक कि आप कुछ नया जोड़ने जा रहे हैं क्यों आप इसे फिर से बनाना चाहते हैं?

आपके प्रश्न में जो तुलना मिली है वह वास्तव में उस प्रतिनिधि का प्रतिनिधि नहीं है जिसकी मैं निंजा उपयोग की अपेक्षा करता हूं। आप ऑब्जेक्ट्स का उपयोग कर रहे एक ही विधि में बाध्यकारी और पुन: बाध्यकारी हैं। मैं कंटेनर सेटअप कहीं और करने की उम्मीद करता हूँ। यह आपको निर्माण को बदलने की अनुमति देता है (ताकि उदाहरण के लिए मॉक ऑब्जेक्ट्स बनाकर परीक्षण करना आसान हो) कोड को बदलने के बिना वास्तव में निर्मित ऑब्जेक्ट का उपयोग करता है।

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