5

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

मैं हमेशा अपने इकाई संदर्भ बनाया है के रूप में मैं एमएस ट्यूटोरियल में देखा है, इसलिए जैसे:

public class UserController : Controller 
{ 
    private DbEntities db = new DbEntities(); 

} 

हाल पढ़ने मुझे बताया गया है कि यह अब नहीं है (अगर यह कभी था) सबसे अच्छा अभ्यास, और एक निर्भरता इंजेक्शन विधि का उपयोग किया जाना चाहिए। निनजेक्ट का अक्सर उल्लेख किया जाता है, लेकिन मैं देख रहा हूं कि आप मेरे पास क्या हैं, उदाहरण के लिए Ninject documentation में दें।

ऐसा होने पर मुझे ऐसा दिखना चाहिए, है ना?

public class UserController : Controller 
{ 
    private DbEntities db; 

    public UserController(DbEntities context) 
    { 
     db = context; 
    } 
} 

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

मुझे खेद है कि अगर मैंने दस्तावेज़ों में कुछ महत्वपूर्ण बात छोड़ दी है, तो मैं इस चरण को समझने के लिए घंटों के लिए मंचों के बीच उछाल रहा हूं।

उत्तर

4

मैं Nuget विधि का इस्तेमाल किया स्थापित करने के लिए है, लेकिन मैं नहीं जानता कि इसका क्या मतलब जब यह कहते हैं "अब अपने मॉड्यूल लोड या RegisterServices विधि में बाइंडिंग परिभाषित करते हैं।" मैं यह कैसे कर सकता हूं, और इकाई एक मॉड्यूल या बाध्यकारी है?

Nuget स्थापना वास्तव में आपके लिए पहले से ही बहुत सी चीजें करता है। सबसे महत्वपूर्ण बात यह है कि यह निंजा को नियंत्रक कारखाने के रूप में स्थापित करता है, जिसका अर्थ है कि निनजेक्ट आपके नियंत्रकों को बनाएगा और आपके द्वारा पंजीकृत सभी निर्भरताओं में गुजरने में सक्षम है।

यदि आप App_Start फ़ोल्डर की जांच करते हैं तो आपको एक फ़ाइल NinjectMVC3.cs मिल जाएगी। पहले से ही एक खाली विधि RegisterServices() है जिसका उपयोग आप अपनी निर्भरताओं को पंजीकृत करने के लिए कर सकते हैं।

आपके उदाहरण के लिए आप DbEntities को हल करने में सक्षम होना चाहिए। सबसे आसान सबसे बुनियादी यह करने के लिए तरीका है:

kernel.Bind<DbEntities>().ToSelf(); 

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

यह आपको एक शुरुआत देना चाहिए - जो दस्तावेज़ आप लिंक करते हैं वह थोड़ा पुराना लगता है। मैं github पर Ninject MVC3 sample को देखने की अनुशंसा करता हूं।

+0

धन्यवाद। मैंने नमूना डाउनलोड किया, लेकिन इसमें बहुत कुछ चल रहा है कि यह कहना मुश्किल है कि क्या कर रहा है।मैं समझता हूँ कि नहीं कैसे बाइंड अभी भी काम कर रहा है, लेकिन उस लाइन सब यह नियंत्रक के निर्माता संदर्भ देने के लिए ले जाता है हो रहा है। क्या आप किसी लेख या ट्यूटोरियल की अनुशंसा कर सकते हैं जो वास्तव में यहां क्या हो रहा है? – Tyrsius

+0

मैं 'http पर लिंक की जाँच होगी: निर्भरता इंजेक्शन के लिए सामान्य रूप में // ninject.org/learn', यह भी पुस्तक" .NET में निर्भरता इंजेक्शन "मार्क सीनैन – BrokenGlass

1

निर्भरता इंजेक्शन पहले भ्रमित लग सकता है, लेकिन यह वास्तव में वास्तव में काफी सरल है।

एक निर्भरता इंजेक्शन "कंटेनर" मूल रूप से एक सामान्य कारखाना है, जिसमें विभिन्न ऑब्जेक्ट आजीवन प्रबंधन सुविधाएं हैं। निनजा, विशेष रूप से, इस फैक्ट्री को भ्रमित करने के लिए सिंटैक्स kernel.Bind() का उपयोग करता है।जब आप kernel.Bind<DbEntities>().ToSelf() कहते हैं तो इसका अर्थ यह है कि जब भी उस प्रकार का अनुरोध किया जाता है तो निनजेक्ट बाध्य प्रकार (इस मामले में डीबीईएनटीटी) का एक उदाहरण बनायेगा। यह अनुरोध आमतौर पर इस तरह दिखता है:

var entities = kernel.Get<DbEntities>(); // Note: don't do this, just an example 

इसके मूल पर, निर्भरता इंजेक्शन यही है। एक सामान्य कारखाना जो मनमाने ढंग से प्रकारों को तुरंत चालू कर सकता है।

हालांकि, इसके मुकाबले इसके लिए बहुत कुछ है। निर्भरता इंजेक्शन की एक अच्छी विशेषता यह है कि यह प्रक्रिया में किसी भी निर्भर प्रकार को भी चालू करेगा। तो, मान लीजिए कि आपके पास नियंत्रक है, और उस नियंत्रक की डीबीईएनटीटी पर निर्भरता है। खैर, जब डी नियंत्रक द्वारा एक नियंत्रक को तुरंत चालू किया जाता है, तो यह निर्भर डीबीईएनटीटी को भी चालू करेगा। नीचे दिया गया कोड देखें। जब MyController instantiated है, DbEntities स्वचालित रूप से (यह मानते हुए आप डि विन्यास में आत्म करने के लिए DbEntities वर्ग के लिए बाध्य है)

var controller = kernel.Get<MyController>(); 

public class MyController : Controller { 
    private DbEntities _entities; 
    public MyController(DbEntities entities) { 
     _entities = entities; 
    } 
} 

यह पुनरावर्ती है instantiated हो जाएगी। कोई भी वर्ग जो तत्काल हो जाता है जिसमें कोई वस्तुएं होती हैं जो स्वयं ही तत्काल हो सकती है, और इसी तरह, और आखिरकार, सब कुछ उसके काम को करने की ज़रूरत है।

अब, एमवीसी के बारे में बड़ी बात यह है कि यह किसी भी डी कंटेनर का स्वचालित रूप से उपयोग करने के लिए अंतर्निहित है। आपको kernel.Get पर कॉल करने की आवश्यकता नहीं है क्योंकि जब यह अनुरोध आता है तो नियंत्रक बनाता है जब फ्रेमवर्क आपके लिए करता है। इस सुविधा को IDependencyResolver कहा जाता है, और यह एक इंटरफेस है कि एमवीसी फ्रेमवर्क तीसरे पक्ष के डी कंटेनर का उपयोग करने की अनुमति देने के लिए उपयोग करता है ढांचे के द्वारा।

आप Nuget पैकेज Ninject.MVC3 का उपयोग कर तो यह आपके लिए अपने आप यह सब कॉन्फिगर करेगा द्वारा Ninject स्थापित करते हैं, और आप केवल RegisterServices करने के लिए अपने बाइंडिंग जोड़ने (की जरूरत है) NinjectMVC3.cs

की धारा

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

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

स्पष्ट है कि, मैं तुम्हें उदाहरण मैं ऊपर देने का उपयोग की सलाह नहीं देते। वे कैसे काम करता है के बारे में सिर्फ सरल चित्र हैं। विशेष रूप से, Get() वाक्यविन्यास को "सेवा स्थान" के रूप में जाना जाता है और इसे खराब माना जाता है। हालांकि, आखिरकार कुछ कोड, कहीं भी कॉल() को कॉल करना होगा, इसे सिर्फ ढांचे में गहरा दफनाया गया है।

जैसा कि एडम का उल्लेख है, सीधे डेटा इकाइयों के संदर्भ में बाध्यकारी एक अच्छा विचार नहीं है, और अंततः आपको इंटरफेस आधारित दृष्टिकोण का उपयोग करने के लिए आगे बढ़ना चाहिए।

+0

द्वारा पर एक नज़र डालें एक ठोस आंकड़ों के एक नियंत्रक बाध्यकारी निर्भरता इंजेक्शन का उपयोग करते समय कार्यान्वयन का उपयोग करें? –

+0

@AdamTuliper - उन क्या ढांचे में पर चला जाता है के सरलीकृत उदाहरण हैं। आदर्श रूप से एक इंटरफेस का उपयोग करेगा, लेकिन मैं उदाहरण की जटिलता में वृद्धि नहीं करना चाहता था। ढांचा ही नियंत्रक का दृष्टांत होगा, लेकिन इंजेक्शन प्रकार हल करने के लिए कॉन्फ़िगर डि कंटेनर का उपयोग, तो यह रूप में अगर नियंत्रक ही बाध्य कर रहे थे। –

+0

@MyerstereMan, धन्यवाद, यह बहुत जानकारीपूर्ण था। स्पष्ट करने के लिए: Ninject का MVC3 के कार्यान्वयन के लिए सेट के बाद से 'IDependencyResolver',' .Get() 'आवश्यक कभी नहीं है? क्या डेस्कटॉप फ्रेमवर्क में '.Get()' का उपयोग किया जाएगा? – Tyrsius

0

मैं कभी यहां एक ठोस प्रकार इंजेक्ट नहीं करता - आप सीधे डेटा एक्सेस कार्यान्वयन के साथ जोड़ रहे हैं।

इसके बजाय IDbContext (या IUnitOfWork) करने के लिए बाध्य - इन इंटरफेस आप, DbContext के समर्थन ठोस कार्यान्वयन के साथ परिभाषित इस तरह से आप आसानी से दूर सार क्या प्रौद्योगिकी का उपयोग कर रहे, जिससे यह अधिक swappable, परीक्षण योग्य, पोषणीय, आदि कर रहे हैं

पूर्व के लिए: http://blogs.planetcloud.co.uk/mygreatdiscovery/post/EF-Code-First-Common-Practices.aspx#disqus_thread

+0

मैं प्रिंसिपल में सहमत हूं, लेकिन एक ठोस प्रकार के लिए बाध्यकारी डीआई की मूल बातें सीखने के बिना इंटरफ़ेस कार्यान्वयन में शामिल होने का एक अच्छा तरीका है। –

+0

@AdamTuliper मैं बाद में इस लेख को पढ़ने के लिए होगा, लेकिन इस समाधान एक बहुत अधिक काम की आवश्यकता है। मुझे समझ में नहीं आता कि मैं एक विशिष्ट कार्यान्वयन के बिना नियंत्रक से अपने संदर्भ पर विशिष्ट इकाई सेट (एसक्यूएल टेबल) कैसे कॉल कर सकता हूं। – Tyrsius

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