5

this question में अच्छे उत्तरों को पढ़ने के बाद, मैंने जस्टिन एथेरेज द्वारा स्क्रीनकास्ट देखा। यह सब बहुत अच्छा लगता है, कम से कम सेटअप के साथ आप अपने कोड से DI प्राप्त करते हैं।आप विन्यास के बिना निर्भरता इंजेक्शन क्यों चाहते हैं?

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

क्या कोई मुझे एक अच्छा उपयोग केस दे सकता है जो एक गैर-कॉन्फ़िगर किए गए DI जैसे Ninject का उपयोग कर मान्य करता है?

उत्तर

10

मुझे नहीं लगता कि आप एक डीआई-फ्रेमवर्क कॉन्फ़िगरेशन के बिना चाहते हैं। मुझे लगता है कि आप कॉन्फ़िगरेशन के साथ एक डी-फ्रेमवर्क चाहते हैं, आपको की आवश्यकता है।

मैं वसंत को एक उदाहरण के रूप में ले जाऊंगा। "पुराने दिनों" में वापस हम सब कुछ कॉन्फ़िगर करने योग्य बनाने के लिए एक्सएमएल फाइलों में सब कुछ डालते थे।

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

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

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

+0

लेकिन किसी भी कॉन्फ़िगरेशन के बारे में क्या नहीं है (जैसे Google guice में) - आप "घटक भूमिकाएं" कैसे निर्दिष्ट करते हैं? – JohnIdol

+0

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

0

यदि आप रिलीज बिल्ड के बाद व्यवहार को बदलना चाहते हैं, तो आपको बाहरी कॉन्फ़िगरेशन का समर्थन करने वाले डी फ्रेमवर्क की आवश्यकता होगी, हां।

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

1

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

तो यह सब इस बात पर निर्भर करता है कि आप अपने आवेदन को कितना कॉन्फ़िगर करने योग्य चाहते हैं। यदि आप कोड पुन: संकलन के बिना कॉन्फ़िगर करने योग्य/प्लग करने योग्य होना चाहते हैं, तो आप कुछ ऐसा चाहते हैं जिसे आप टेक्स्ट या एक्सएमएल फाइलों के माध्यम से कॉन्फ़िगर कर सकें।

0

आपको PRISM in .NET (यह .NET में समग्र अनुप्रयोगों को करने के लिए सर्वोत्तम प्रथाओं को पढ़ना चाहिए) पढ़ना चाहिए। इन सर्वोत्तम प्रथाओं में प्रत्येक मॉड्यूल एक साझा कंटेनर के अंदर उनके कार्यान्वयन प्रकार को "एक्सपोज़" करें। इस तरह प्रत्येक मॉड्यूल में "इस इंटरफ़ेस के लिए कार्यान्वयन प्रदान करने वाले" पर स्पष्ट उत्तरदायित्व हैं।मुझे लगता है कि यह समझ जाएगा कि जब आप समझेंगे कि PRISM कैसे काम करता है।

+0

कूल, मैं उसमें देख लूंगा। –

3

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

+0

न केवल यूनिट परीक्षण - यह उन हिस्सों के लिए नकली घटकों के साथ एप्लिकेशन के परीक्षण/dev संस्करण को तैनात करने का एक शानदार तरीका है, जिन्हें आप परीक्षण नहीं करना चाहते हैं (या ग्राहकों को दिखाएं)। – Domchi

+0

ठीक है, लेकिन मुझे इसके लिए निनजेक की आवश्यकता क्यों होगी? –

1

मैं परीक्षण के लिए DI का उपयोग दूसरा कर दूंगा। मैं केवल परीक्षण के लिए इस समय डीआई का उपयोग करने पर विचार करता हूं, क्योंकि हमारे आवेदन को किसी कॉन्फ़िगरेशन-आधारित लचीलापन की आवश्यकता नहीं होती है - इस समय इस पर विचार करने के लिए भी बहुत बड़ा है।

DI क्लीनर, अधिक अलग डिज़ाइन का नेतृत्व करता है - और यह पूरे दौर में फायदे देता है।

0

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

public class ZipProcessor : IFileProcessor 
{ 
    IZipService ZipService; 
    IEmailService EmailService; 

    public void Process(string fileName) 
    { 
    ZipService.Zip(fileName, Path.ChangeFileExtension(fileName, ".zip")); 
    EmailService.SendEmailTo(................); 
    } 
} 

इस कक्षा को वास्तव में ज़िप और ईमेलिंग करने की आवश्यकता क्यों होगी जब आप कक्षाओं को आपके लिए ऐसा करने के लिए समर्पित कर सकें? जाहिर है, आप नहीं करेंगे, लेकिन यह मेरे बिंदु तक केवल एक लीड है :-)

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

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

var processor = Container.Resolve<ZipProcessor>(); 

तो अब आप न केवल सफाई से वर्ग की कार्यक्षमता साझा कार्यक्षमता से अलग कर दिया है, लेकिन आप भी एक दूसरे के किसी भी स्पष्ट ज्ञान होने से उपभोक्ता/प्रदाता को रोका है। यह पढ़ने के लिए कोड को समझना आसान बनाता है क्योंकि एक ही समय में विचार करने के लिए कम कारक हैं।

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

//Mock the ZIP 
var mockZipService = MockRepository.GenerateMock<IZipService>(); 
mockZipService.Expect(x => x.Zip("Hello.xml", "Hello.zip")); 

//Mock the email send 
var mockEmailService = MockRepository.GenerateMock<IEmailService>(); 
mockEmailService.Expect(x => x.SendEmailTo(.................); 

//Test the processor 
var testSubject = new ZipProcessor(mockZipService, mockEmailService); 
testSubject.Process("Hello.xml"); 

//Assert it used the services in the correct way 
mockZipService.VerifyAlLExpectations(); 
mockEmailService.VerifyAllExceptions(); 

तो संक्षेप में। आप इसे पर करना चाहते हैं 01: उपभोक्ताओं को स्पष्ट रूप से यह जानने से रोकें कि कौन सा प्रदाता अपनी आवश्यक सेवाओं को लागू करता है, जिसका अर्थ है कि कोड पढ़ने पर एक बार समझने के लिए कम नहीं है। 02: यूनिट परीक्षण को आसान बनाएं।

पीट

+0

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

5

मैं krosenvold के साथ एक रास्ते पर हूँ, यहाँ, केवल कम पाठ के साथ: सबसे अनुप्रयोगों के भीतर, आप प्रति आवश्यक "सेवा" एक ठीक एक कार्यान्वयन है। हम केवल उन अनुप्रयोगों को नहीं लिखते हैं जहां प्रत्येक ऑब्जेक्ट को प्रत्येक सेवा के 10 या अधिक कार्यान्वयन की आवश्यकता होती है। तो यह एक आसान तरीका कहने का अर्थ होगा "यह डिफ़ॉल्ट कार्यान्वयन है, इस सेवा का उपयोग कर सभी वस्तुओं का 99% इसके साथ खुश होंगे"।

परीक्षणों में, आप आमतौर पर एक विशिष्ट नकली उपयोग करते हैं, इसलिए वहां किसी भी कॉन्फ़िगर की आवश्यकता नहीं है (क्योंकि आप मैन्युअल रूप से तारों को करते हैं)।

यह सम्मेलन-ओवर-कॉन्फ़िगरेशन के बारे में है।अधिकांश समय, कॉन्फ़िगरेशन केवल डीई फ्रेमवर्क को पहले से ही पता होना चाहिए कि डंप फ्रेमवर्क पहले से ही पता होना चाहिए :)

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

3

मैं अपने ब्लॉग पर इस टिप्पणी को प्राप्त किया, Nate Kohari से:

खुशी है कि आप Ninject का उपयोग कर विचार कर रहे हैं! निनजेस इस दृष्टिकोण को लेता है कि आपके डी फ्रेमवर्क की कॉन्फ़िगरेशन वास्तव में आपके एप्लिकेशन का हिस्सा है, और सार्वजनिक रूप से कॉन्फ़िगर करने योग्य नहीं होना चाहिए। यदि आप कुछ बाइंडिंग कॉन्फ़िगर करने योग्य चाहते हैं, तो आप आसानी से अपना निनजा मॉड्यूल अपने app.config को पढ़ सकते हैं। कोड में आपकी बाइंडिंग होने से आपको XML की वर्बोजिटी से बचाता है, और आपको टाइप-सुरक्षा, रिफैक्टरिबिलिटी और इंटेलिजेंस देता है।

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