2012-01-13 5 views
18

का उपयोग कैसे करें मैं आज निनजेक्ट का उपयोग करने और कुछ प्रश्न पूछने की कोशिश कर रहा हूं। सबसे पहले मुझे सभी रचनाकारों पर इंजेक्ट विशेषता का उपयोग करने की आवश्यकता है जिसे मैं इंजेक्शन का उपयोग करना चाहता हूं। यह वास्तव में लंगड़ा डिजाइन की तरह लगता है? क्या मुझे कर्नेल बनाने की ज़रूरत है, फिर हर जगह मैं इंजेक्शन कक्षा में प्रवेश करता हूं?निनजा

उत्तर

22

First of all do I need to use the Inject attribute on all constructors that I want to use injection for. This seems like a really lame design?

नहीं, आपको वास्तव में ऐसा करने की ज़रूरत नहीं है। चूंकि आप एएसपी.नेट एमवीसी के साथ काम करते हैं तो आप केवल Ninject.MVC3 Nuget पैकेज स्थापित कर सकते हैं। यह आपको App_Start फ़ोल्डर में NinjectMVC3 कक्षा से शुरू कर देगा। आप निंजेक्ट के साथ अपने इंटरफेस/कक्षाओं को पंजीकृत करने के लिए RegisterServices विधि का उपयोग कर सकते हैं। उन सभी नियंत्रकों जिनके पास उन इंटरफेस पर निर्भरता है, उन्हें निंजा द्वारा स्वचालित रूप से हल किया जाएगा, इंजेक्ट विशेषता की कोई आवश्यकता नहीं है।

Do I need to create a Kernel then use that everywhere I pass in an injected class?

नहीं - क्या आप और अधिक Service Locator pattern की तरह लगता है का वर्णन कर रहे हैं, इंजेक्शन निर्भरता नहीं - आप के बजाय गिरी का उपयोग कर विशेष कक्षाओं के भीतर उन्हें हल करने का, निर्माता में आदर्श अपने निर्भरता में पारित करने के लिए चाहते हैं। वहां केवल एक केंद्रीय संरचना जड़ होनी चाहिए जहां हल किया जा रहा है, जो कि ऊपर वर्णित RegisterServices विधि या संरचना के रूट में है, एक अलग निनजा मॉड्यूल वहां तत्काल है - बाद का दृष्टिकोण आपको थोड़ा अधिक लचीलापन और मॉड्यूलरिटी (कोई पन नहीं देगा) इरादा) यह बदलने में कि आप अपनी निर्भरताओं को कैसे हल करते हैं।

यहां एक अच्छा beginner's tutorial on dependency injection with Ninject and MVC3 है।

+0

इस जानकारी के लिए धन्यवाद। मैंने अब [इंजेक्ट] विशेषता हटा दी है। मैंने एक ट्यूटोरियल वीडियो देखा और यही वह जगह है जहां मैंने ऐसा करना सीखा। मुझे अब क्या करना है संकल्पित कंक्रीट क्लास में पास पैरामीटर है जिसके लिए मैं WithConstructorArgument का उपयोग कर रहा हूं लेकिन मुझे अभी भी यह त्रुटि मिलती है: इस ऑब्जेक्ट के लिए कोई पैरामीटर रहित कन्स्ट्रक्टर परिभाषित नहीं किया गया है। –

+0

प्लस, अब मैं उलझन में हूं, आपके द्वारा पोस्ट किया गया लिंक भी मानक केरल दृष्टिकोण का उपयोग करता है। डी की मेरी समझ यह थी कि कंटेनर स्वचालित रूप से निर्भरताओं को हल करता है (आपके द्वारा सेट की गई बाइंडिंग के आधार पर)। –

+0

@ सची: आपको 'साथ कॉन्स्टस्ट्रक्टर आर्ग्यूमेंट()' की आवश्यकता नहीं है, या तो अगर पैरामीटर को पारित करने की आवश्यकता है तो निनजेक्ट के साथ भी हल किया जाता है - इसे ग्राफ – BrokenGlass

58

निनजेक्ट के साथ शुरू करने का सबसे अच्छा तरीका छोटा शुरू करना है। new की तलाश करें।

कहीं भी आपके आवेदन के बीच में, आप किसी अन्य कक्षा के अंदर एक कक्षा बना रहे हैं। इसका मतलब है कि आप निर्भरता बना रहे हैं। निर्भरता इंजेक्शन में एम्बेडिंग के बजाय आमतौर पर कन्स्ट्रक्टर के माध्यम से उन निर्भरताओं के माध्यम सेमें गुज़र रहा है।

कहें कि आपके पास इस तरह की एक कक्षा है, जो स्वचालित रूप से वर्ड में एक विशिष्ट प्रकार का नोट बनाने के लिए उपयोग की जाती है। (यह एक परियोजना मैं हाल ही में काम पर किया है के समान है।)

class NoteCreator 
{ 
    public NoteHost Create() 
    { 
     var docCreator = new WordDocumentCreator(); 
     docCreator.CreateNewDocument(); 
     [etc.] 

WordDocumentCreator एक वर्ग है कि (वर्ड का एक उदाहरण, आदि बनाने) माइक्रोसॉफ्ट वर्ड में एक नया दस्तावेज़ बनाने की बारीकियों संभालती है। मेरी कक्षा, NoteCreator, पर WordDocumentCreator पर अपना काम करने के लिए निर्भर करता है।

मुसीबत, है अगर किसी दिन हम एक बेहतर शब्द संसाधक के लिए जाने का फैसला, मैं सभी स्थानों पर जहां WordDocumentCreator instantiated है मिल जाने के लिए और के बजाय WordPerfectDocumentCreator का दृष्टांत के लिए उन्हें बदलना होगा।

अब कल्पना है कि मैं इस तरह देखने के लिए मेरी कक्षा बदलने के लिए:

class NoteCreator 
{ 
    WordDocumentCreator docCreator; 

    public NoteCreator(WordDocumentCreator docCreator) // constructor injection 
    { 
     this.docCreator = docCreator; 
    } 

    public NoteHost Create() 
    { 
     docCreator.CreateNewDocument(); 
     [etc.] 

मेरे कोड है कि ज्यादा नहीं बदला है; मैंने Create विधि के भीतर किया है, new के साथ लाइन को हटा दें। लेकिन अब मैं अपनी निर्भरता इंजेक्शन कर रहा हूं।आइए एक और छोटा सा परिवर्तन करना है:

class NoteCreator 
{ 
    IDocumentCreator docCreator; 

    public NoteCreator(IDocumentCreator docCreator) // change to interface 
    { 
     this.docCreator = docCreator; 
    } 

    public NoteHost Create() 
    { 
     docCreator.CreateNewDocument(); 
     [etc.] 

बजाय एक ठोसWordDocumentCreator में उत्तीर्ण होने की, मैं एक CreateNewDocument विधि के साथ एक IDocumentCreatorइंटरफ़ेस निकाला है। अब मैं में कक्षा में प्रवेश कर सकता हूं जो उस इंटरफ़ेस को लागू करता है, और सभी NoteCreator को ऐसा करने की विधि को कॉल करना है।

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

दूसरी चीज़ जो मुझे करने की ज़रूरत है निंजा कॉन्फ़िगर करें।

class MyAppModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IDocumentCreator>() 
      .To<WordDocumentCreator>(); 

यह Ninject बताता है कि जब मैं एक वर्ग है कि, कहीं लाइन नीचे, एक IDocumentCreator की आवश्यकता बनाने का प्रयास है, यह एक WordDocumentCreator बना सकते हैं और है कि उपयोग करना चाहिए: आवश्यक टुकड़ा एक वर्ग है कि इस तरह दिखता है। प्रक्रिया निनजेक्ट इस तरह से दिखता है:

  • एप्लिकेशन का MainWindow बनाएं। इसके कन्स्ट्रक्टर को NoteCreator की आवश्यकता है।
  • ठीक है, तो नोट नोटर बनाएं। लेकिन इसके कन्स्ट्रक्टर को IDocumentCreator की आवश्यकता है।
  • मेरा कॉन्फ़िगरेशन कहता है कि IDocumentCreator के लिए, मुझे WordDocumentCreator का उपयोग करना चाहिए। तो WordDocumentCreator बनाएं।
  • अब मैं नोटक्रिएटर को WordDocumentCreator पास कर सकता हूं।
  • और अब मैं NoteCreator को MainWindow पर पास कर सकता हूं।

इस प्रणाली की सुंदरता तीन गुना है।

सबसे पहले, यदि आप कुछ कॉन्फ़िगर करने में विफल रहते हैं, तो आप तुरंत जान लेंगे, क्योंकि आपकी ऑब्जेक्ट्स जैसे ही आपका ऑर्डर चलाया जाता है। निनजेक्ट आपको एक उपयोगी त्रुटि संदेश देगा जिसमें कहा गया है कि आपका IDocumentCreator (उदाहरण के लिए) हल नहीं किया जा सकता है।

दूसरा, यदि प्रबंधन बाद में एक बेहतर शब्द संसाधक के उपयोगकर्ता जनादेश, तुम सब करने की ज़रूरत है

  • एक WordPerfectDocumentCreator कि IDocumentCreator लागू करता लिखें।
  • MyAppModule ऊपर IDocumentCreator को WordPerfectDocumentCreator पर बाध्यकारी बदलें।

तीसरा, मैं अपने NoteCreator का परीक्षण करना चाहते हैं, मैं एक असलीWordDocumentCreator (या मैं उपयोग कर रहा हूँ जो कुछ भी) में पारित करने के लिए नहीं है। मैं नकली एक में पास कर सकता हूं। इस तरह से मैं एक परीक्षा लिख ​​सकता हूं कि मानता है मेरा IDocumentCreator सही तरीके से काम करता है, और केवल NoteCreator में चलती भागों का परीक्षण करता है। मेरा नकली IDocumentCreator कुछ भी नहीं करेगा लेकिन सही प्रतिक्रिया लौटाएगा, और मेरा परीक्षण यह सुनिश्चित करेगा कि NoteCreator सही काम करता है।

इस तरह अपने अनुप्रयोगों को कैसे व्यवस्थित करने के बारे में अधिक जानकारी के लिए, मार्क सीमैन की हाल की पुस्तक, Dependency Injection in .NET पर एक नज़र डालें। दुर्भाग्यवश, इसमें निनजेक्ट शामिल नहीं है, लेकिन इसमें कई अन्य डी ढांचे को शामिल किया गया है, और यह बताता है कि मैंने ऊपर वर्णित तरीके से अपने आवेदन को कैसे व्यवस्थित किया है।

माइकल फेदरस द्वारा Working Effectively With Legacy Code पर भी एक नज़र डालें। वह उपरोक्त के परीक्षण पक्ष के बारे में बात करता है: व्यवहार को अलग करने और इसे परीक्षण के तहत प्राप्त करने के उद्देश्य से इंटरफेस को तोड़ने और नकली में कैसे गुजरना है।

+4

के रूप में सोचें निर्भरता इंजेक्शन के साथ-साथ निंजा दोनों के लिए वास्तव में अच्छी व्याख्या! धन्यवाद और मैं इसे आगे के संदर्भों के लिए अपने Evernote पर कॉपी कर रहा हूं। – Tarik

+0

@ किरालेसा यह वास्तव में एक उत्कृष्ट स्पष्टीकरण है। अब तक मैंने जो पढ़ा है, उनमें से एक स्पष्ट और समझदार है। शुरुआत में आप क्या कर रहे हैं उसे गरीब आदमी की निर्भरता इंजेक्शन कहा जाता है? –

+0

वाह सबसे अच्छा स्पष्टीकरण मैंने अब तक देखा है इस आदमी को आलू दें। +1 –

7

डॉक्स न भूलें, जिसमें एक परिचय भी शामिल है, मुझे लगता है कि on the Ninject Wiki से पूछे जाने वाले प्रश्नों के अनुसार मुझे बहुत उपयुक्त लगेगा। यदि आप इसे समाप्त होने के बिना निनजेक्ट का उपयोग करने की कोशिश कर रहे हैं तो आप केवल खुद को परेशान कर रहे हैं।

थोड़ी देर के लिए अपने बुकमार्क बार पर table of contents चिपकाएं।

मैं डीई आधारित आर्किटेक्चर के लिए एक साथी पुस्तक के रूप में Mark Seemann के Dependency Injection in .Net की अत्यधिक अनुशंसा भी कर सकता हूं (भले ही यह सीधे निनजेक्ट को कवर न करे)।