डिपेंडेंसी इंजेक्शन के लिए सबसे अच्छी परिभाषा क्या है?


10

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

डेवलपर्स के लिए DI का वर्णन करने का सबसे अच्छा तरीका समझाने में कोई भी मेरी मदद कर सकता है?


2
यहाँ चुनौती यह है कि डीआई की बहुत सारी परस्पर विरोधी परिभाषाएँ हैं। मैं "शुद्ध DI" रुख लेता हूं: यदि मेरे पास एक फ़ंक्शन है जो सभी राज्य, डेटा आदि प्रदान करने के लिए अपने मापदंडों पर निर्भर करता है, तो वह फ़ंक्शन DI का उपयोग कर रहा है। अन्य चरम पर, कुछ तर्क देंगे कि डीआई फ्रेमवर्क के बिना, कोई निर्भरता इंजेक्शन नहीं है (हालांकि वे निश्चित रूप से गलत हैं;))। इसलिए जब तक आप किसी परिभाषा को खत्म नहीं कर सकते, आप यह
डेविड अरनो

इसलिए, जैसा कि मैं समझता हूं, यह केवल मेरी समस्या नहीं है।
टियागो सम्पीओ



यह सब इसके लिए नीचे आता है: निर्भरता इंजेक्शन एक तकनीक है जिसका उपयोग निर्भरता उलटा प्राप्त करने के लिए किया जाता है; बाकी सब कुछ केवल अतिरिक्त सामान है जो उसके ऊपर बनाया गया है। ध्यान दें कि इन दो शब्दों में "निर्भरता" शब्द के कुछ अलग अर्थ हैं। निर्भरता इंजेक्शन में, यह उस घटक को संदर्भित करता है जो कोड पर निर्भर है। निर्भरता व्युत्क्रम में, यह स्वयं (निर्देशित) संबंध को संदर्भित करता है - वह जो हम उलटना चाहते हैं। उत्तरार्द्ध लक्ष्य है, इसलिए मुख्य पेशेवरों और विपक्ष समान हैं; प्लस वास्तविक कार्यान्वयन से संबंधित कुछ अतिरिक्त चिंताएं, जैसे कि वस्तु जीवनकाल प्रबंधन।
फिलिप मिलोवानोविक

जवाबों:


22

निर्भरता का इंजेक्शन एक भयानक नाम (IMO) 1 है न कि सीधी अवधारणा के लिए। यहाँ एक उदाहरण है:

  1. आपके पास एक विधि (या विधियों के साथ वर्ग) है जो X करता है (जैसे डेटाबेस से डेटा पुनर्प्राप्त करता है)
  2. एक्स करने के हिस्से के रूप में, कहा गया है कि विधि एक आंतरिक संसाधन (जैसे DbContext) बनाती है और प्रबंधित करती है । इस आंतरिक संसाधन को एक निर्भरता कहा जाता है
  3. आप संसाधन (अर्थात DbContext) बनाने और प्रबंधित करने की विधि को हटा देते हैं और इस संसाधन को प्रदान करने के लिए कॉलर की जिम्मेदारी (विधि पैरामीटर के रूप में या वर्ग के तात्कालिकता पर) प्रदान करते हैं
  4. अब आप निर्भरता इंजेक्शन कर रहे हैं।


[१] : मैं एक निचले स्तर की पृष्ठभूमि से आता हूं और मुझे निर्भरता इंजेक्शन सीखने में महीनों लग गए क्योंकि नाम का अर्थ है कि यह DLL इंजेक्शन की तरह कुछ अधिक जटिल होगा । तथ्य यह है कि विज़ुअल स्टूडियो (और हम सामान्य रूप से डेवलपर्स) .NET लाइब्रेरी (DLL, या असेंबली ) को संदर्भित करते हैं कि एक परियोजना निर्भर करती है क्योंकि निर्भरताएं बिल्कुल भी मदद नहीं करती हैं। यहां तक ​​कि डिपेंडेंसी वॉकर (निर्भरExe) जैसी कोई चीज भी है ।


[संपादित करें] मुझे लगा कि कुछ डेमो कोड कुछ के लिए काम आएगा, इसलिए यहाँ एक (C # में) है।

निर्भरता इंजेक्शन के बिना:

public class Repository : IDisposable
{
    protected DbContext Context { get; }

    public Repository()
    {
        Context = new DbContext("name=MyEntities");
    }

    public void Dispose()
    {
        Context.Dispose();
    }
}

आपका उपभोक्ता तब कुछ ऐसा करेगा:

using ( var repository = new Repository() )
{
    // work
}

निर्भरता इंजेक्शन पैटर्न के साथ लागू एक ही वर्ग इस तरह होगा:

public class RepositoryWithDI
{
    protected DbContext Context { get; }

    public RepositoryWithDI(DbContext context)
    {
        Context = context;
    }
}

अब यह कॉल करने वाले की DbContextज़िम्मेदारी है कि वह आपकी कक्षा में तुरंत और पास (ग़लती, इंजेक्शन ) करे:

using ( var context = new DbContext("name=MyEntities") )
{
    var repository = new RepositoryWithDI(context);

    // work
}

3
इसे विकिपीडिया में जोड़ा जाना चाहिए।
Evorlor

2
अब एक DbContext को तुरंत कॉल करने की कॉलर की ज़िम्मेदारी है - मुझे लगता है कि यह सभी आवश्यक निर्भरताओं को तत्काल करने के लिए एप्लिकेशन के प्रवेश बिंदु की जिम्मेदारी होगी। इसलिए उपभोक्ता को केवल अनुबंध में निर्भरता के रूप में आवश्यक प्रकार का परिचय देना होगा।
फाबियो

@ फैबियो यह हो सकता है। (उस स्थिति में, कॉल करने वाले की ज़िम्मेदारी उस संसाधन को प्रदान करने की होगी जो एप्लीकेशन स्टार्टअप में त्वरित तरीके से कॉल की जा रही विधि / वर्ग के लिए थी।) मेरे उदाहरण में, यह नहीं है, हालाँकि, क्योंकि यह निर्भरता इंजेक्शन की अवधारणा को समझाने की आवश्यकता नहीं है। ।
मार्क.2377

5

अमूर्त अवधारणाओं को अक्सर वास्तविक दुनिया सादृश्य का उपयोग करके बेहतर ढंग से समझाया जाता है। यह मेरा जाना-सा उपमा है:

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

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

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

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

यह सही नहीं है, लेकिन यह प्रमुख विशेषता को उजागर करता है: उपभोक्ता को नियंत्रण देना । अंतर्निहित जीत-जीत यह है कि अब आपको अपनी खुद की निर्भरता हासिल नहीं करनी है, और आपका उपभोक्ता निर्भरता की अपनी पसंद में पीछे नहीं है।


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

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

2
आप निश्चित रूप से सही हैं, लेकिन मैं मदद नहीं कर सकता, लेकिन मुझे लगता है कि मुझे एक ठोस उदाहरण की आवश्यकता होगी - जैसे कि मेरी भूख को मिटाने के लिए वास्तविक फाइल सिस्टम या डेटाबेस नहीं होना, लेकिन शायद यह सिर्फ मेरा संकीर्ण डेवलपर दृश्य है :)
रोबी

1

इसका सरल उत्तर है:

सबसे पहले एक वर्ग की एक अच्छी तरह से परिभाषित जिम्मेदारी होनी चाहिए, और इस दायरे के बाहर सब कुछ उस वर्ग के बाहर रखा जाना चाहिए। इसके साथ ही, डिपेंडेंसी इंजेक्शन तब है जब आप चिंताओं के इस अलगाव को प्राप्त करने के लिए "तृतीय-पक्ष" की मदद से कक्षा ए में अन्य वर्ग बी से एक कार्यक्षमता इंजेक्षन करते हैं, वर्ग ए को कुछ ऑपरेशन को पूरा करने में मदद करते हैं जो इसके दायरे से बाहर है।

.नेट कोर एक बहुत अच्छा उदाहरण है जो आप दे सकते हैं क्योंकि यह ढांचा निर्भरता इंजेक्शन का बहुत उपयोग करता है। आम तौर पर, जिन सेवाओं को आप इंजेक्ट करना चाहते हैं, वे startup.csफ़ाइल में स्थित हैं ।

ज़रूर, छात्र को कुछ अवधारणाओं जैसे कि बहुरूपता, इंटरफेस और ओओपी डिज़ाइन सिद्धांतों के बारे में पता होना चाहिए।


0

संक्षेप में, एक सरल अवधारणा के आसपास बहुत सारे फुलाना और चारपाई है।

जब आप कोड में इसे काफी सरलता से कर सकते हैं, तो " मुझे किस फ्रेमवर्क का उपयोग करना चाहिए " से छेड़छाड़ करना बहुत आसान है ।

यह वह परिभाषा है जिसका मैं व्यक्तिगत रूप से उपयोग करता हूं:

वाई। की निर्भरता के साथ व्यवहार एक्स को देखते हुए निर्भरता इंजेक्शन में किसी भी वाई की आपूर्ति करने की सुविधा शामिल है जो वाई के उदाहरण के लिए मानदंड को संतुष्ट करता है, भले ही आपके पास एक न हो।

कुछ उदाहरण हो सकते हैं जहां वाई एक फाइल सिस्टम या डेटाबेस कनेक्शन है।

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

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


0

हम उस व्यवहार को एक पैरामीटर के माध्यम से फ़ंक्शन में डालने की विधि के माध्यम से रनटाइम पर एक फ़ंक्शन का व्यवहार प्रदान करते हैं।

रणनीति पैटर्न निर्भरता इंजेक्शन का एक उत्कृष्ट उदाहरण है।


0

इस अधिकार को करने के लिए, हमें पहले निर्भरता और इंजेक्शन को परिभाषित करना होगा।

  • निर्भरता: किसी भी संसाधन को एक ऑपरेशन की आवश्यकता होती है।
  • इंजेक्शन: उस संसाधन को ऑपरेशन में पास करना, आमतौर पर एक विधि के तर्क के रूप में।

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

मान लीजिए कि आप इसके बजाय गुणों का उपयोग करते हैं और आप उन्हें A और B नाम देते हैं। यदि आप Op1 और Op2 में नाम बदलते हैं, तो आप Add विधि को तोड़ देंगे। या आपका आईडीई आपके लिए सभी नामों को अपडेट करेगा, बिंदु यह है कि विधि को भी अपडेट करना होगा क्योंकि इसमें बाहरी संसाधनों पर निर्भरता है।

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

बिंदु: अपने मूल व्यवहार के लिए एक विधि की कार्यक्षमता को कम करने के लिए और इसके वातावरण से विधि को कम करने के लिए। आपको दूसरा करने से पहला मिलता है, आप इसे निर्भरता इंजेक्शन की परिभाषा मान सकते हैं।

लाभ: चूंकि विधि के पर्यावरण के लिए निर्भरता समाप्त हो गई है, इसलिए विधि में परिवर्तन पर्यावरण को प्रभावित नहीं करेगा और इसके विपरीत। => आवेदन को बनाए रखने (संशोधित) करना आसान हो जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.