निर्भरता इंजेक्शन क्या है?


3074

निर्भरता इंजेक्शन के बारे में विशिष्ट प्रश्नों के साथ पहले से ही कई प्रश्न पोस्ट किए गए हैं , जैसे कि इसका उपयोग कब करना है और इसके लिए क्या रूपरेखाएँ हैं। तथापि,

निर्भरता इंजेक्शन क्या है और इसका उपयोग कब और क्यों / नहीं किया जाना चाहिए?


डिपेंडेंसी इंजेक्शन यहाँ पर मेरी चर्चा देखें ।
केविन एस।

33
मैं लिंक के बारे में टिप्पणियों से सहमत हूं। मैं समझ सकता हूं कि आप किसी और को संदर्भित करना चाहते हैं। लेकिन कम से कम यह जोड़ें कि आप उन्हें क्यों लिंक कर रहे हैं और यह लिंक Google द्वारा उपयोग किए जा सकने वाले अन्य लिंक से बेहतर है
क्रिश्चियन पायने

@AR: तकनीकी रूप से, डिपेंडेंसी इंजेक्शन IoC का एक विशेष रूप नहीं है। बल्कि, IoC एक तकनीक है जिसका उपयोग निर्भरता इंजेक्शन प्रदान करने के लिए किया जाता है। अन्य तकनीकों का उपयोग डिपेंडेंसी इंजेक्शन प्रदान करने के लिए किया जा सकता है (हालांकि IoC आम उपयोग में एकमात्र है), और IoC का उपयोग कई अन्य समस्याओं के लिए भी किया जाता है।
सीन रेली

DI के बारे में मैंने अब तक जो सबसे अच्छी व्याख्या की है, वह Google के Guice (रस के रूप में स्पष्ट) http://code.google.com/p/google-guice/wiki/Motivation?tm=6
Raj

136
लिंक के बारे में, याद रखें कि वे अक्सर एक या दूसरे तरीके से गायब हो जाते हैं। SO उत्तरों में मृत लिंक की संख्या बढ़ रही है। इससे जुड़ा हुआ लेख कितना भी अच्छा क्यों न हो, अगर आपको नहीं मिल रहा है तो यह बिल्कुल भी अच्छा नहीं है।
DOK

जवाबों:


1931

निर्भरता इंजेक्शन अन्य वस्तुओं या ढांचे (निर्भरता इंजेक्टर) पर निर्भरता से गुजर रहा है ।

निर्भरता इंजेक्शन परीक्षण को आसान बनाता है। इंजेक्शन कंस्ट्रक्टर के माध्यम से किया जा सकता है ।

SomeClass() इसके निर्माता निम्नानुसार हैं:

public SomeClass() {
    myObject = Factory.getObject();
}

समस्या : यदि myObjectडिस्क एक्सेस या नेटवर्क एक्सेस जैसे जटिल कार्य शामिल हैं, तो यूनिट परीक्षण करना कठिन है SomeClass()। प्रोग्रामर को मज़ाक करना पड़ता है myObjectऔर फैक्ट्री कॉल को रोक सकता है ।

वैकल्पिक समाधान :

  • myObjectकंस्ट्रक्टर के पास एक तर्क के रूप में पासिंग
public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

myObject सीधे पारित किया जा सकता है जो परीक्षण को आसान बनाता है।

  • एक सामान्य विकल्प एक डू-नो कंस्ट्रक्टर को परिभाषित कर रहा है । आश्रितों के माध्यम से निर्भरता का इंजेक्शन लगाया जा सकता है। (h / t @ मायकेवेला)।
  • मार्टिन फाउलर एक तीसरे विकल्प (h / t @MarcDix) का दस्तावेज बनाते हैं, जहां कक्षाएं स्पष्ट रूप से निर्भरता के इच्छुक प्रोग्रामर के लिए एक इंटरफ़ेस लागू करती हैं।

निर्भरता इंजेक्शन के बिना इकाई परीक्षण में घटकों को अलग करना कठिन है।

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


25
यह स्वीकार करते हुए कि बेन हॉफस्टीन के रेफरेंसेटो मार्टिन फाउलर का लेख इस विषय पर 'अवश्य पढ़ें' को इंगित करने के रूप में आवश्यक है, मैं डब्ल्यूडीएस के उत्तर को स्वीकार कर रहा हूं क्योंकि यह वास्तव में एसओ के प्रश्न का उत्तर देता है।
ए.आर.

121
+1 स्पष्टीकरण और प्रेरणा के लिए: उन वस्तुओं का निर्माण करना जिन पर एक वर्ग किसी और की समस्या पर निर्भर करता है । यह कहने का एक और तरीका है कि DI कक्षाओं को अधिक सामंजस्यपूर्ण बनाता है (उनकी कम जिम्मेदारियां हैं)।
फ्यूहरमैनटर

13
आप कहते हैं कि "कंस्ट्रक्टर में निर्भरता" पारित हो गई है, लेकिन जैसा कि मैं समझता हूं कि यह कड़ाई से सच नहीं है। यह अभी भी निर्भरता इंजेक्शन है यदि निर्भरता एक वस्तु के रूप में सेट होने के बाद वस्तु को तत्काल, सही किया गया है?
माइक वेला

1
@ मायकेवेला हां, यह सही है। यह ज्यादातर मामलों में कोई वास्तविक अंतर नहीं करता है, हालांकि आमतौर पर गुण थोड़ा अधिक लचीला होते हैं। मैं उस बिंदु को इंगित करने के लिए पाठ को थोड़ा संपादित करूंगा।
wds

2
अब तक मुझे मिले सबसे अच्छे उत्तरों में से एक, इस प्रकार मुझे इसे सुधारने में वास्तव में दिलचस्पी है। यह निर्भरता इंजेक्शन के तीसरे रूप का विवरण याद कर रहा है: इंटरफ़ेस इंजेक्शन
मार्क डिक्स

2351

मैंने अब तक की सबसे अच्छी परिभाषा जेम्स शोर से एक है :

"निर्भरता इंजेक्शन" 5-प्रतिशत अवधारणा के लिए 25-डॉलर का शब्द है। [...] निर्भरता इंजेक्शन का अर्थ है किसी वस्तु को उसके उदाहरण चर देना। [...]।

मार्टिन फाउलर का एक लेख है जो उपयोगी भी साबित हो सकता है।

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

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


35
मुझे जेम्स के लेख की व्याख्या पसंद है, विशेष रूप से अंत: "फिर भी, आपको किसी भी दृष्टिकोण पर अचंभा करना होगा जो तीन अवधारणाओं ('TripPlanner,' 'CabAarios,' और 'AirlineAgency') को लेता है, उन्हें नौ-प्लस कक्षाओं में बदल देता है और फिर एप्लिकेशन लॉजिक की एक भी लाइन लिखे जाने से पहले गोंद कोड और कॉन्फ़िगरेशन एक्सएमएल की दर्जनों लाइनें जोड़ता है। " यह वही है जो मैंने बहुत बार (दुख की बात) देखा है - कि निर्भरता इंजेक्शन (जो उसके द्वारा समझाए अनुसार प्रति अच्छा है) उन चीजों का दुरुपयोग करने के लिए दुरुपयोग किया जाता है जो आसानी से किया जा सकता था - लेखन "सहायक" कोड को समाप्त कर रहा है ...
मैट

2
पुन :: "तत्काल और गुजर वस्तुओं (निर्भरता) स्पष्ट रूप से बस के रूप में इंजेक्शन के रूप में इंजेक्शन के रूप में अच्छा है।"। तो लोगों ने ऐसा करने की रूपरेखा क्यों बनाई?
dzieciou

13
इसी कारण से कि हर फ्रेमवर्क मिलता है (या कम से कम मिलना चाहिए) लिखा होता है: क्योंकि बहुत बार-बार / बॉयलरप्लेट कोड होता है जिसे एक निश्चित जटिलता तक पहुंचने के बाद आपको लिखना पड़ता है। समस्या कई बार लोगों को एक ढांचे के लिए पहुंच जाएगी, यहां तक ​​कि जब यह सख्त जरूरत नहीं है।
थियागो अरैसिस

14
5-प्रतिशत अवधारणा के लिए $ 25 शब्द मृत है। यहाँ एक अच्छा लेख है जो मेरी मदद कर रहा है: codeproject.com/Articles/615139/…
Christine

@Matt विन्यास फाइल बस "चरम निर्णय को" उसके चरम पर ले जाती है - "वास्तविक रनटाइम तक निर्णय स्थगित करें"। डैगर और विशेष रूप से डैगर ने मेरी राय में "एसेम्बली असेंबली के समय तक निर्णय को स्थगित कर दिया" मिठाई स्थान पाया।
Thorbjørn Ravn Andersen

645

ढीले युग्मन के संदर्भ में मुझे यह मजेदार उदाहरण मिला :

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

उदाहरण के लिए, किसी Carवस्तु पर विचार करें ।

A Carपहियों, इंजन, ईंधन, बैटरी, आदि पर निर्भर करता है। परंपरागत रूप से हम ऑब्जेक्ट की परिभाषा के साथ इस तरह के आश्रित वस्तुओं के ब्रांड को परिभाषित करते हैं Car

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

class Car{
  private Wheel wh = new NepaliRubberWheel();
  private Battery bt = new ExcideBattery();

  //The rest
}

यहां, Carऑब्जेक्ट निर्भर वस्तुओं को बनाने के लिए जिम्मेदार है।

क्या होगा यदि हम इसके आश्रित वस्तु के प्रकार को बदलना चाहते हैं - कहते हैं Wheel- प्रारंभिक NepaliRubberWheel()पंचर के बाद ? हमें अपनी नई निर्भरता के साथ कार ऑब्जेक्ट को फिर से बनाने की आवश्यकता है ChineseRubberWheel(), लेकिन केवल Carनिर्माता ही ऐसा कर सकता है।

फिर Dependency Injectionहमारे लिए क्या करता है ...?

निर्भरता इंजेक्शन का उपयोग करते समय, वस्तुओं को संकलित समय (कार निर्माण समय) के बजाय रन समय पर उनकी निर्भरता दी जाती है । ताकि अब Wheelहम जब चाहें बदल सकें । यहाँ, dependency( wheel) को Carरन टाइम पर इंजेक्ट किया जा सकता है ।

निर्भरता इंजेक्शन का उपयोग करने के बाद:

यहाँ, हम कर रहे हैं इंजेक्शन लगाने निर्भरता रनटाइम पर (पहिया और बैटरी)। इसलिए शब्द: निर्भरता इंजेक्शन।

class Car{
  private Wheel wh; // Inject an Instance of Wheel (dependency of car) at runtime
  private Battery bt; // Inject an Instance of Battery (dependency of car) at runtime
  Car(Wheel wh,Battery bt) {
      this.wh = wh;
      this.bt = bt;
  }
  //Or we can have setters
  void setWheel(Wheel wh) {
      this.wh = wh;
  }
}

स्रोत: निर्भरता इंजेक्शन समझना


20
जिस तरह से मैं इसे समझता हूं, वह किसी अन्य वस्तु के हिस्से के रूप में एक नई वस्तु को तात्कालिक करने के बजाय, हम उक्त वस्तु को इंजेक्ट कर सकते हैं, जब इसकी आवश्यकता होती है और इस प्रकार पहली वस्तु की निर्भरता को हटा दिया जाता है। क्या वह सही है?
जेलीबीनमाइन

मैंने इसे यहां एक कॉफ़ी शॉप के उदाहरण के साथ वर्णित किया है: digigene.com/design-patterns/dependency-injection-coffeeshop
अली नेम

11
वास्तव में यह सादृश्य पसंद है क्योंकि यह एक साधारण सादृश्य का उपयोग करके स्पष्ट अंग्रेजी है। मैं टोयोटा हूँ, पहले से ही बंद रोलिंग करने के लिए डिजाइन से एक कार बनाने पर बहुत अधिक आर्थिक रूप से खर्च किया और आदमी बिजली, लाइन को इकट्ठा कहो अगर वहाँ मौजूदा सम्मानित टायर निर्माता हैं, मैं क्यों एक टायर निर्माण डिवीजन यानी करने के लिए बनाने के लिए नए सिरे से शुरू कर देना चाहिए newएक टायर? मैं नही। मुझे बस इतना करना है कि उनसे (परम के माध्यम से इंजेक्शन) खरीदें, स्थापित करें और वाह-लाह! इसलिए, प्रोग्रामिंग पर वापस आकर, एक C # प्रोजेक्ट को मौजूदा लाइब्रेरी / क्लास का उपयोग करने की आवश्यकता है,
इसको

(con't), .. बाहरी पुस्तकालय / वर्ग, या इसे DLL से 2-जोड़ें। जब तक हमें यह नहीं देखना है कि इस बाहरी वर्ग के अंदर क्या है, इसे DLL के रूप में जोड़ना एक आसान तरीका है। तो विकल्प 1 newयह है, विकल्प 2 इसे पास के रूप में पास करता है। हो सकता है सटीक न हो, लेकिन समझने में आसान आसान बेवकूफ।
Jeb50

1
@JeliBeanMachine (एक टिप्पणी के लिए बहुत देर से जवाब के लिए खेद है ..) ऐसा नहीं है कि हम पहिएदार वस्तु या बैटरी वस्तु पर पहली वस्तु की निर्भरता को हटा देते हैं, यह है कि हम इसे निर्भरता से गुजारें, ताकि हम उदाहरण या कार्यान्वयन को बदल सकें निर्भरता। इससे पहले: कार में नेपालीब्रबरवेल पर एक हार्डकोड निर्भरता है। के बाद: कार में व्हील के उदाहरण पर एक इंजेक्शन निर्भरता है।
मिकेल ओहलसन

263

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

उदाहरण के लिए, इन मामलों पर विचार करें:

public class PersonService {
  public void addManager( Person employee, Person newManager ) { ... }
  public void removeManager( Person employee, Person oldManager ) { ... }
  public Group getGroupByManager( Person manager ) { ... }
}

public class GroupMembershipService() {
  public void addPersonToGroup( Person person, Group group ) { ... }
  public void removePersonFromGroup( Person person, Group group ) { ... }
} 

इस उदाहरण में, के कार्यान्वयन PersonService::addManagerऔर PersonService::removeManagerका एक उदाहरण की आवश्यकता होगी GroupMembershipServiceताकि इसकी काम करने के लिए में। डिपेंडेंसी इंजेक्शन के बिना, ऐसा करने का पारंपरिक तरीका दोनों के कार्यों में उस इंस्टेंस विशेषता GroupMembershipServiceके निर्माण PersonServiceऔर उपयोग में एक नया इंस्टेंट करना होगा । हालाँकि, यदि निर्माता के GroupMembershipServiceपास कई चीजें हैं जिनकी आवश्यकता है, या अभी तक बदतर है, तो कुछ आरंभीकरण "बसने" हैं जिन्हें कॉल करने की आवश्यकता है GroupMembershipService, कोड जल्दी से बढ़ता है, और PersonServiceअब न केवल पर निर्भर करता है GroupMembershipServiceबल्कि बाकी सब भी है GroupMembershipServiceनिर्भर करता है। इसके अलावा, लिंकेज को GroupMembershipServiceहार्डकोड किया गया है, PersonServiceजिसका अर्थ है कि आप "डमी अप" नहीं कर सकते हैंGroupMembershipService परीक्षण के प्रयोजनों के लिए, या अपने आवेदन के विभिन्न भागों में एक रणनीति पैटर्न का उपयोग करने के लिए।

डिपेंडेंसी इंजेक्शन के साथ, GroupMembershipServiceअपने भीतर की तात्कालिकता के बजाय PersonService, आप इसे या तो PersonServiceकंस्ट्रक्टर के पास भेज देंगे , या फिर इसका एक स्थानीय उदाहरण सेट करने के लिए एक संपत्ति (गेट्टर और सेटर) जोड़ देंगे । इसका मतलब यह है कि PersonServiceअब आपको इस बारे में चिंता करने की ज़रूरत नहीं है कि कैसे बनाया जाए GroupMembershipService, यह केवल उन लोगों को स्वीकार करता है जो इसे दिया गया है, और उनके साथ काम करता है। इसका मतलब यह भी है कि जो कुछ भी उप-वर्ग है GroupMembershipService, या GroupMembershipServiceइंटरफ़ेस को लागू करता है उसे "इंजेक्ट" किया जा सकता है PersonService, और PersonServiceपरिवर्तन के बारे में जानने की आवश्यकता नहीं है।


29
यदि आप DI का उपयोग कर एक ही कोड उदाहरण AFTER दे सकते तो बहुत अच्छा होता
CodyBugstein

170

स्वीकृत उत्तर एक अच्छा है - लेकिन मैं यह जोड़ना चाहूंगा कि कोड में हार्डकोडेड स्थिरांक से क्लासिक परहेज करना डीआई को बहुत पसंद है।

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

DI ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग की दुनिया में इसके अनुरूप है। निरंतर शाब्दिकों के बजाय वहां के मूल्य पूरे ऑब्जेक्ट हैं - लेकिन कोड को कक्षा कोड से बाहर ले जाने का कारण समान है - ऑब्जेक्ट अधिक बार बदलते हैं फिर कोड जो उनका उपयोग करता है। एक महत्वपूर्ण मामला जहां इस तरह के बदलाव की आवश्यकता है, परीक्षण है।


18
+1 "ऑब्जेक्ट अधिक बार बदलते हैं फिर कोड जो उनका उपयोग करता है"। सामान्य करने के लिए, फ्लक्स के बिंदुओं पर एक अप्रत्यक्ष जोड़ें। प्रवाह के बिंदु के आधार पर, अप्रत्यक्ष को विभिन्न नामों से पुकारा जाता है !!
चेतन

139

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

public class Car
{
    public Car()
    {
        GasEngine engine = new GasEngine();
        engine.Start();
    }
}

public class GasEngine
{
    public void Start()
    {
        Console.WriteLine("I use gas as my fuel!");
    }
}

और कार क्लास को तुरंत करने के लिए हम अगले कोड का उपयोग करेंगे:

Car car = new Car();

इस कोड के साथ समस्या है कि हम कसकर GasEngine को युग्मित करते हैं और अगर हम इसे ElectricEngine में बदलने का निर्णय लेते हैं तो हमें कार वर्ग को फिर से लिखना होगा। और जितना बड़ा आवेदन उतना ही अधिक मुद्दों और सिरदर्द के लिए हमें नए प्रकार के इंजन को जोड़ना और उपयोग करना होगा।

इस दृष्टिकोण के साथ दूसरे शब्दों में यह है कि हमारी उच्च स्तरीय कार क्लास निचले स्तर के GasEngine क्लास पर निर्भर है जो कि SOLID से डिपेंडेंसी इनवर्जन प्रिंसिपल (DIP) का उल्लंघन करती है। डीआईपी सुझाव देता है कि हमें अमूर्तता पर निर्भर होना चाहिए, न कि ठोस वर्गों पर। तो इसे संतुष्ट करने के लिए हम नीचे IEngine इंटरफ़ेस और फिर से कोड की तरह परिचय देते हैं:

    public interface IEngine
    {
        void Start();
    }

    public class GasEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I use gas as my fuel!");
        }
    }

    public class ElectricityEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I am electrocar");
        }
    }

    public class Car
    {
        private readonly IEngine _engine;
        public Car(IEngine engine)
        {
            _engine = engine;
        }

        public void Run()
        {
            _engine.Start();
        }
    }

अब हमारा कार वर्ग केवल IEngine इंटरफ़ेस पर निर्भर है, इंजन का विशिष्ट कार्यान्वयन नहीं। अब, केवल ट्रिक यह है कि हम कार का एक उदाहरण कैसे बनाते हैं और इसे GasEngine या ElectricEngine जैसे वास्तविक कंक्रीट इंजन वर्ग देते हैं। यही कारण है कि जहां है निर्भरता इंजेक्शन में आता है।

   Car gasCar = new Car(new GasEngine());
   gasCar.Run();
   Car electroCar = new Car(new ElectricityEngine());
   electroCar.Run();

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

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

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

इसके अलावा, जब हमारे पास कई निर्भरताएं हैं तो नियंत्रण (IoC) कंटेनरों का उपयोग करना बहुत अच्छा अभ्यास है जो हम बता सकते हैं कि हमारे सभी निर्भरता के लिए कौन से इंटरफेस को लागू किया जाना चाहिए और हम इसका निर्माण करते समय हमारे लिए उन निर्भरता को हल कर सकते हैं। हमारी वस्तु। उदाहरण के लिए, हम IoC कंटेनर के लिए मैपिंग में निर्दिष्ट कर सकते हैं कि IEngine निर्भरता को GasEngine वर्ग में मैप किया जाना चाहिए और जब हम IoC कंटेनर को हमारे कार वर्ग के एक उदाहरण के लिए कहेंगे , तो यह स्वतः ही एक GasEngine निर्भरता के साथ हमारी कार कक्षा का निर्माण करेगा। में पारित।

अद्यतन: हाल ही में जूली लर्मन से EF कोर के बारे में देखा और DI के बारे में उसकी छोटी परिभाषा को भी पसंद किया।

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


2
सिर्फ जिज्ञासा से बाहर, यह रणनीति पैटर्न से कैसे अलग है? यह पैटर्न एल्गोरिदम को घेर रहा है और उन्हें विनिमेय बना रहा है। ऐसा लगता है कि निर्भरता इंजेक्शन और रणनीति पैटर्न बहुत समान हैं।
अमृत

110

आइए कल्पना करें कि आप मछली पकड़ने जाना चाहते हैं:

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

  • निर्भरता इंजेक्शन के साथ, कोई और पूरी तैयारी का ख्याल रखता है और आपके लिए आवश्यक उपकरण उपलब्ध कराता है। आप नाव (मछली का इंजेक्शन) प्राप्त करेंगे, मछली पकड़ने की छड़ी और चारा - सभी उपयोग करने के लिए तैयार हैं।


59
फ़्लिपसाइड है, कल्पना कीजिए कि आप अपने बाथरूम को फिर से बनाने के लिए एक प्लम्बर किराए पर लेते हैं, जो तब कहता है, "महान, यहां उन उपकरणों और सामग्री की एक सूची है जो मुझे आपके लिए प्राप्त करने की आवश्यकता है"। क्या यह प्लंबर का काम नहीं होना चाहिए?
jscs

ताकि किसी को किसी ऐसे व्यक्ति की देखभाल करने की आवश्यकता हो, जिसके पास कोई व्यवसाय नहीं है .. लेकिन फिर भी वह नाव, छड़ी और चारा की सूची एकत्र करने का निर्णय लेता है - यद्यपि उपयोग करने के लिए तैयार है।
चोकोस

22
@JoshCaswell नहीं, प्लंबर की नौकरी करने वाले की नौकरी जाएगी। क्लाइंट के रूप में आपको प्लंबिंग की आवश्यकता होती है। उसके लिए आपको एक प्लम्बर चाहिए। प्लंबर को इसके उपकरण चाहिए। उन पाने के लिए, यह नलसाजी कंपनी द्वारा सुसज्जित है। एक ग्राहक के रूप में आप यह जानना नहीं चाहते हैं कि प्लंबर क्या करता है या उसे क्या चाहिए। एक प्लम्बर के रूप में आप जानते हैं कि आपको क्या चाहिए, लेकिन आप बस अपना काम करना चाहते हैं, सब कुछ नहीं। प्लंबर नियोक्ता के रूप में आप अपने प्लंबर को उन लोगों के घरों में भेजने से पहले उनकी ज़रूरत के लिए जिम्मेदार होते हैं।
सारा

@kai मैं आपकी बात समझता हूं। सॉफ्टवेयर में हम एक कारखाने के बारे में बात कर रहे हैं, सही है? लेकिन DI का आमतौर पर यह भी मतलब है कि वर्ग किसी कारखाने का उपयोग नहीं करता है क्योंकि वह अभी भी इंजेक्शन नहीं है। आप, ग्राहक, आपको उपकरण देने के लिए नियोक्ता (कारखाने) से संपर्क करने की आवश्यकता होगी, ताकि आप प्लंबर को पास कर सकें। क्या यह नहीं है कि यह वास्तव में एक कार्यक्रम में कैसे काम करेगा? इसलिए जब ग्राहक (कॉलिंग क्लास / फंक्शन / जो भी हो) को उपकरण खरीदने की जरूरत नहीं होती है, फिर भी उन्हें मिडिल मैन होना चाहिए ताकि वे इसे नियोक्ता (फैक्टरी) से प्लम्बर (इंजेक्टेड क्लास) तक सुनिश्चित कर सकें।
KingOfAllTrades

1
@KingOfAllTrades: निश्चित रूप से कुछ बिंदु पर आपके पास किसी को नियुक्त करने और संगठन तैयार करने के लिए होना चाहिए, या आप कोई प्लंबर नहीं हैं। लेकिन आपके पास ग्राहक नहीं है। ग्राहक सिर्फ एक प्लंबर के लिए पूछता है, और उसे पहले से ही अपना काम करने की जरूरत होती है। DI के साथ, आपके पास अभी भी निर्भरता को पूरा करने के लिए कुछ कोड हैं। लेकिन आप इसे उस कोड से अलग कर रहे हैं जो वास्तविक काम करता है। यदि आप इसे पूरी तरह से लेते हैं, तो आपकी वस्तुएं केवल उनकी निर्भरता को ज्ञात करती हैं, और ऑब्जेक्ट-ग्राफ़-बिल्डिंग बाहर होती है, अक्सर इनिट कोड।
cHao

102

डिपेंडेंसी इंजेक्शन और डिपेंडेंसी इंजेक्शन कंटेनर के बारे में यह सबसे सरल स्पष्टीकरण है जो मैंने कभी देखा है:

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

  • एप्लिकेशन को फू (जैसे नियंत्रक) की आवश्यकता है, इसलिए:
  • अनुप्रयोग फू बनाता है
  • एप्लिकेशन फू को बुलाता है
    • फू को बार की जरूरत है (जैसे एक सेवा), इसलिए:
    • फू बर बनाता है
    • फू को बार कहते हैं
      • बार को बिम (एक सेवा, एक भंडार, ...) की जरूरत है, इसलिए:
      • बार बिम बनाता है
      • बार कुछ करता है

निर्भरता इंजेक्शन के साथ

  • एप्लिकेशन को फू की जरूरत है, जिसे बार की जरूरत है, जिसे बिम की जरूरत है, इसलिए:
  • आवेदन बिम बनाता है
  • आवेदन बार बनाता है और यह Bim देता है
  • अनुप्रयोग फू बनाता है और इसे बार देता है
  • एप्लिकेशन फू को बुलाता है
    • फू को बार कहते हैं
      • बार कुछ करता है

एक निर्भरता इंजेक्शन कंटेनर का उपयोग करना

  • एप्लिकेशन को फू की आवश्यकता है:
  • आवेदन कंटेनर से फू जाता है, इसलिए:
    • कंटेनर बिम बनाता है
    • कंटेनर बार बनाता है और इसे Bim देता है
    • कंटेनर फू बनाता है और उसे बार देता है
  • एप्लिकेशन फू को बुलाता है
    • फू को बार कहते हैं
      • बार कुछ करता है

निर्भरता इंजेक्शन और निर्भरता इंजेक्शन कंटेनर अलग चीजें हैं:

  • डिपेंडेंसी इंजेक्शन बेहतर कोड लिखने की एक विधि है
  • DI कंटेनर निर्भरता को इंजेक्ट करने में मदद करने के लिए एक उपकरण है

आपको निर्भरता इंजेक्शन करने के लिए कंटेनर की आवश्यकता नहीं है। हालांकि एक कंटेनर आपकी मदद कर सकता है।



55

क्या "निर्भरता इंजेक्शन" का मतलब केवल मानकीकृत निर्माणकर्ताओं और सार्वजनिक बसने वालों का उपयोग करना नहीं है?

जेम्स शोर का लेख तुलना के लिए निम्नलिखित उदाहरण दिखाता है

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

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

निर्भरता इंजेक्शन के साथ निर्माता:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}

निश्चित रूप से DI संस्करण में आप कोई तर्क निर्माता में myDatabase ऑब्जेक्ट को इनिशियलाइज़ करना नहीं चाहेंगे? ऐसा लगता है कि कोई बिंदु नहीं है और यदि आप ओवरलोड निर्माणकर्ता को कॉल किए बिना डस्टफ को कॉल करने की कोशिश करते हैं तो एक अपवाद को फेंकने की सेवा करेंगे?
मैट विल्को

केवल तभी new DatabaseThingie()एक वैध myDatabase उदाहरण उत्पन्न नहीं करता है।
जेनगुडॉल

40

निर्भरता इंजेक्शन अवधारणा को समझने के लिए सरल बनाने के लिए। चलो एक बल्ब चालू करने के लिए स्विच बटन का एक उदाहरण लेते हैं।

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

स्विच को पहले से पता होना चाहिए कि मैं किस बल्ब से जुड़ा हुआ हूं (हार्ड-कोडेड निर्भरता)। इसलिए,

स्विच -> PermanentBulb // स्विच सीधे स्थायी बल्ब से जुड़ा है, आसानी से परीक्षण संभव नहीं है

Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}

निर्भरता इंजेक्शन के साथ

स्विच ही जानता है कि मुझे जो भी बल्ब चालू है उसे चालू / बंद करना होगा। इसलिए,

स्विच -> बल्ब 1 या बल्ब 2 या नाइटबल्ब (इंजेक्शन की निर्भरता)

Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}

स्विच और बल्ब के लिए संशोधित जेम्स उदाहरण:

public class SwitchTest { 
  TestToggleBulb() { 
    MockBulb mockbulb = new MockBulb(); 

    // MockBulb is a subclass of Bulb, so we can 
    // "inject" it here: 
    Switch switch = new Switch(mockBulb); 

    switch.ToggleBulb(); 
    mockBulb.AssertToggleWasCalled(); 
  } 
}

public class Switch { 
  private Bulb myBulb; 

  public Switch() { 
    myBulb = new Bulb(); 
  } 

  public Switch(Bulb useThisBulbInstead) { 
    myBulb = useThisBulbInstead; 
  } 

  public void ToggleBulb() { 
    ... 
    myBulb.Toggle(); 
    ... 
  } 
}`

36

निर्भरता इंजेक्शन (DI) क्या है?

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

DI, DIP और SOLID

विशेष रूप से, रॉबर्ट सी मार्टिन के प्रतिमान में उन्मुखी डिजाइन वस्तु की ठोस सिद्धांतों , DIके संभावित कार्यान्वयन में से एक है निर्भरता उलट सिद्धांत (DIP)DIP है Dकी SOLIDमंत्र अन्य DIP कार्यान्वयन सेवा लोकेटर, और प्लगइन पैटर्न में शामिल हैं -।

डीआईपी का उद्देश्य कक्षाओं के बीच तंग, ठोस निर्भरता को कम करना है, और इसके बजाय, एक अमूर्त के माध्यम से युग्मन को ढीला करना है, जिसे भाषा और दृष्टिकोण के आधार पर interface, abstract classया pure virtual class, के माध्यम से प्राप्त किया जा सकता है ।

डीआईपी के बिना, हमारा कोड (मैंने इसे 'उपभोग करने वाला वर्ग' कहा है) सीधे एक ठोस निर्भरता से जुड़ा होता है और अक्सर यह जानने की जिम्मेदारी के साथ बोझ भी होता है, और इस निर्भरता का एक उदाहरण, अर्थात् प्रबंधन, प्रबंधन करना।

"I need to create/use a Foo and invoke method `GetBar()`"

जबकि डीआईपी के आवेदन के बाद, आवश्यकता को ढीला Fooकर दिया गया है , और निर्भरता के जीवनकाल को प्राप्त करने और प्रबंधित करने की चिंता को हटा दिया गया है:

"I need to invoke something which offers `GetBar()`"

DIP (और DI) का उपयोग क्यों करें?

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

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

इसे विभिन्न तरीकों से देखा जा सकता है:

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

कब करें DI का इस्तेमाल?

  • जहां एक समान कार्यान्वयन के लिए आश्रित को स्थानापन्न करने की आवश्यकता होगी,
  • किसी भी समय जहां आपको अपनी निर्भरता के अलगाव में एक वर्ग के तरीकों का परीक्षण करने की आवश्यकता होगी,
  • जहां एक निर्भरता के जीवनकाल की अनिश्चितता वारंट प्रयोग हो सकती है (जैसे अरे, MyDepClassधागा सुरक्षित है - क्या होगा अगर हम इसे एक सिंगलटन बनाते हैं और सभी उपभोक्ताओं में एक ही उदाहरण इंजेक्ट करते हैं?)

उदाहरण

यहाँ एक सरल C # कार्यान्वयन है। नीचे दिए गए उपभोक्ता वर्ग को देखते हुए:

public class MyLogger
{
   public void LogRecord(string somethingToLog)
   {
      Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog);
   }
}

हालाँकि सहज रूप से, यह staticदो अन्य वर्गों पर निर्भरता है, System.DateTimeऔर System.Console, जो न केवल लॉगिंग आउटपुट विकल्पों को सीमित करता है (कंसोल पर लॉगिंग बेकार होगा यदि कोई नहीं देख रहा है), लेकिन इससे भी बदतर, यह निर्भरता को देखते हुए स्वचालित रूप से परीक्षण करना मुश्किल है एक गैर-नियतात्मक प्रणाली घड़ी।

हालाँकि हम DIPइस वर्ग पर लागू कर सकते हैं , एक निर्भरता के रूप में टाइमस्टैम्पिंग की चिंता को समाप्त करके, MyLoggerकेवल एक सरल इंटरफ़ेस के लिए युग्मन :

public interface IClock
{
    DateTime Now { get; }
}

हम Consoleएब्स्ट्रैक्शन पर निर्भरता को भी ढीला कर सकते हैं , जैसे कि ए TextWriter। निर्भरता इंजेक्शन आमतौर पर या तो constructorइंजेक्शन के रूप में लागू किया जाता है (एक सेवन वर्ग के निर्माता के लिए एक पैरामीटर के रूप में एक निर्भरता के लिए एक अमूर्त पासिंग) या Setter Injection(एक setXyz()सेटर या निर्भरता के साथ निर्भरता गुजर रहा है {set;}। परिभाषित संपत्ति के साथ संपत्ति )। कंस्ट्रक्टर इंजेक्शन को प्राथमिकता दी जाती है, क्योंकि यह गारंटी देता है कि निर्माण के बाद वर्ग एक सही स्थिति में होगा, और आंतरिक निर्भरता क्षेत्रों को readonly(C #) या final(जावा) के रूप में चिह्नित करने की अनुमति देता है । इसलिए उपरोक्त उदाहरण पर कंस्ट्रक्टर इंजेक्शन का उपयोग करना, यह हमें छोड़ देता है:

public class MyLogger : ILogger // Others will depend on our logger.
{
    private readonly TextWriter _output;
    private readonly IClock _clock;

    // Dependencies are injected through the constructor
    public MyLogger(TextWriter stream, IClock clock)
    {
        _output = stream;
        _clock = clock;
    }

    public void LogRecord(string somethingToLog)
    {
        // We can now use our dependencies through the abstraction 
        // and without knowledge of the lifespans of the dependencies
        _output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog);
    }
}

(एक ठोस Clockप्रदान करने की आवश्यकता है, जो निश्चित रूप से वापस लौट सकता है DateTime.Nowऔर दो आश्रितों को आईओसी कंटेनर द्वारा कंस्ट्रक्टर इंजेक्शन प्रदान करने की आवश्यकता है)

एक स्वचालित यूनिट टेस्ट बनाया जा सकता है, जो निश्चित रूप से यह साबित करता है कि हमारा लकड़हारा सही ढंग से काम कर रहा है, क्योंकि अब हम निर्भरता पर नियंत्रण रखते हैं - समय, और हम लिखित आउटपुट पर जासूसी कर सकते हैं:

[Test]
public void LoggingMustRecordAllInformationAndStampTheTime()
{
    // Arrange
    var mockClock = new Mock<IClock>();
    mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45));
    var fakeConsole = new StringWriter();

    // Act
    new MyLogger(fakeConsole, mockClock.Object)
        .LogRecord("Foo");

    // Assert
    Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString());
}

अगला कदम

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

  • प्रत्येक अमूर्त और कॉन्फ़िगर किए गए कंक्रीट कार्यान्वयन के बीच मानचित्रण (उदाहरण के लिए "किसी भी समय उपभोक्ता किसी से अनुरोध करता है IBar, ConcreteBarउदाहरण के लिए वापस लौटें " )
  • नीतियों को प्रत्येक निर्भरता के जीवन प्रबंधन के लिए स्थापित किया जा सकता है, उदाहरण के लिए, प्रत्येक उपभोक्ता उदाहरण के लिए एक नई वस्तु बनाने के लिए, सभी उपभोक्ताओं के बीच एक सिंगलटन निर्भरता उदाहरण साझा करने के लिए, एक ही निर्भरता उदाहरण को एक ही धागे में साझा करने के लिए, आदि।
  • .Net में, IoC कंटेनर प्रोटोकॉल के बारे में जानते हैं जैसे कि IDisposableऔर Disposingकॉन्फ़िगर जीवन प्रबंधन के अनुरूप निर्भरता की जिम्मेदारी लेंगे ।

आमतौर पर, एक बार IoC कंटेनरों को कॉन्फ़िगर / बूटस्ट्रैप किया गया है, वे पृष्ठभूमि में मूल रूप से काम करते हैं, जिससे कोडर निर्भरता के बारे में चिंता करने के बजाय कोड पर ध्यान केंद्रित करने की अनुमति देता है।

DI- अनुकूल कोड की कुंजी वर्गों के स्थिर युग्मन से बचना है, और निर्भरता के निर्माण के लिए नए () का उपयोग नहीं करना है

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

लेकिन लाभ कई हैं, विशेष रूप से आपकी रुचि के वर्ग का पूरी तरह से परीक्षण करने की क्षमता में।

नोट : new ..()POCO / POJO / Serialization DTOs / Entity रेखांकन / बेनामी JSON अनुमानों एट अल - अर्थात "डेटा केवल" वर्ग या रिकॉर्ड - निर्माण या उपयोग किए गए तरीकों से निर्मित / मैपिंग / प्रोजेक्शन (प्रक्षेपण ) को निर्भरता के रूप में नहीं माना जाता है। यूएमएल भावना) और डीआई के अधीन नहीं। newइनका उपयोग करना ठीक है।


1
समस्या डीआईपी है! = DI। डीआईपी कार्यान्वयन से अमूर्तन को हटाने के बारे में है: ए। उच्च-स्तरीय मॉड्यूल को निम्न-स्तर के मॉड्यूल पर निर्भर नहीं होना चाहिए। दोनों को अमूर्तता पर निर्भर होना चाहिए। बी। विवरण विवरण पर निर्भर नहीं होना चाहिए। विवरण अमूर्तता पर निर्भर होना चाहिए। DI, वस्तु के उपयोग से वस्तु निर्माण को कम करने का एक तरीका है।
रिकार्डो रिवाल्डो

हां, अंकल बॉब के ठोस प्रतिमान में, मेरे पैराग्राफ 2 में, "डीआईपी के संभावित कार्यान्वयन में से एक डीआई" में स्पष्ट रूप से कहा गया है । मैंने यह पहले वाली पोस्ट में भी स्पष्ट कर दिया है ।
स्टुअर्टएलसी

25

डिपेंडेंसी इंजेक्शन (DI) का पूरा बिंदु एप्लीकेशन सोर्स कोड को साफ और स्थिर रखने के लिए है :

  • निर्भरता आरंभीकरण कोड की सफाई
  • स्थिर निर्भरता की परवाह किए बिना

व्यावहारिक रूप से, हर डिज़ाइन पैटर्न भविष्य की परिवर्तनों को न्यूनतम फ़ाइलों को प्रभावित करने के लिए चिंताओं को अलग करता है।

DI का विशिष्ट डोमेन निर्भरता कॉन्फ़िगरेशन और आरंभीकरण का प्रतिनिधिमंडल है।

उदाहरण: शैल स्क्रिप्ट के साथ DI

यदि आप कभी-कभी जावा के बाहर काम करते हैं, तो याद रखें कि sourceकई स्क्रिप्टिंग भाषाओं (शेल, टीसीएल, आदि) या यहां तक importकि पायथन में भी इस उद्देश्य के लिए दुरुपयोग कैसे किया जाता है।

सरल dependent.shस्क्रिप्ट पर विचार करें :

#!/bin/sh
# Dependent
touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

स्क्रिप्ट निर्भर है: यह अपने आप सफलतापूर्वक निष्पादित नहीं होगा ( archive_filesपरिभाषित नहीं है)।

आप कार्यान्वयन स्क्रिप्ट archive_filesमें परिभाषित archive_files_zip.shकरते हैं ( zipइस मामले में उपयोग करते हुए):

#!/bin/sh
# Dependency
function archive_files {
    zip files.zip "$@"
}

sourceसीधे निर्भरता में कार्यान्वयन स्क्रिप्ट के बजाय , आप एक injector.sh"कंटेनर" का उपयोग करते हैं जो दोनों "घटकों" को लपेटता है:

#!/bin/sh 
# Injector
source ./archive_files_zip.sh
source ./dependent.sh

archive_files निर्भरता सिर्फ कर दिया गया है इंजेक्शन में निर्भर स्क्रिप्ट।

आप निर्भरता को इंजेक्ट कर सकते हैं जो archive_filesउपयोग कर tarया लागू करता है xz

उदाहरण: DI को हटाना

यदि dependent.shस्क्रिप्ट सीधे निर्भरता का उपयोग करती है, तो दृष्टिकोण को निर्भरता लुकअप कहा जाएगा (जो निर्भरता इंजेक्शन के विपरीत है ):

#!/bin/sh
# Dependent

# dependency look-up
source ./archive_files_zip.sh

touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

अब समस्या यह है कि आश्रित "घटक" को स्वयं आरंभीकरण करना पड़ता है।

"घटक" का स्रोत कोड न तो साफ है और न ही स्थिर है क्योंकि निर्भरता के आरंभ में हर बदलाव के लिए "घटकों" के स्रोत कोड फ़ाइल के लिए नए रिलीज की आवश्यकता होती है।

आखरी श्ब्द

DI को बड़े पैमाने पर जोर नहीं दिया गया है और जावा फ्रेमवर्क की तरह लोकप्रिय बनाया गया है।

लेकिन यह चिंताओं को विभाजित करने के लिए एक सामान्य दृष्टिकोण है:

  • अनुप्रयोग विकास ( एकल स्रोत कोड जारी जीवनचक्र)
  • अनुप्रयोग परिनियोजन ( स्वतंत्र जीवन चक्र के साथ कई लक्ष्य वातावरण)

केवल निर्भरता लुकअप के साथ कॉन्फ़िगरेशन का उपयोग करना मदद नहीं करता है क्योंकि कॉन्फ़िगरेशन पैरामीटर की संख्या प्रति निर्भरता (जैसे नया प्रमाणीकरण प्रकार) के साथ-साथ समर्थित प्रकार की निर्भरता की संख्या (जैसे नया डेटाबेस प्रकार) बदल सकती है।


मैं अपनी निर्भरता को पूरा करने के लिए एक विशेष वर्ग (परीक्षण) को पूरा करने की क्षमता को डीआई के लिए एक उद्देश्य के रूप में जोड़ूंगा।
डेविड

22

उपरोक्त सभी उत्तर अच्छे हैं, मेरा उद्देश्य अवधारणा को सरल तरीके से समझाना है ताकि बिना प्रोग्रामिंग ज्ञान के कोई भी अवधारणा को समझ सके

निर्भरता इंजेक्शन डिजाइन पैटर्न में से एक है जो हमें सरल तरीके से जटिल सिस्टम बनाने में मदद करता है।

हम अपने दिन-प्रतिदिन के जीवन में इस पैटर्न के कई प्रकार के आवेदन देख सकते हैं। कुछ उदाहरण टेप रिकॉर्डर, वीसीडी, सीडी ड्राइव आदि हैं।

रील-टू-रील पोर्टेबल टेप रिकॉर्डर, 20 वीं शताब्दी के मध्य तक।

उपरोक्त छवि रील-टू-रील पोर्टेबल टेप रिकॉर्डर, 20 वीं शताब्दी के मध्य की छवि है। स्रोत

एक टेप रिकॉर्डर मशीन का प्राथमिक उद्देश्य रिकॉर्ड या प्लेबैक ध्वनि है।

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

  1. हम मशीन के अंदर रील रख सकते हैं
  2. हम रील के लिए एक हुक प्रदान कर सकते हैं जहां इसे रखा जा सकता है।

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

जैसे बुद्धिमान निर्भरता इंजेक्शन केवल घटक की विशिष्ट कार्यक्षमता पर ध्यान केंद्रित करने के लिए निर्भरता को बाहरी करने की प्रक्रिया है ताकि एक जटिल प्रणाली बनाने के लिए स्वतंत्र घटकों को एक साथ युग्मित किया जा सके।

निर्भरता इंजेक्शन का उपयोग करके हमने जो मुख्य लाभ प्राप्त किए हैं।

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

अब एक दिन ये अवधारणा प्रोग्रामिंग दुनिया में प्रसिद्ध रूपरेखाओं का आधार बनती है। स्प्रिंग एंगुलर आदि इस अवधारणा के शीर्ष पर निर्मित प्रसिद्ध सॉफ्टवेयर फ्रेमवर्क हैं

निर्भरता इंजेक्शन वस्तुओं के उदाहरणों को बनाने के लिए उपयोग किया जाने वाला एक पैटर्न है जिसे अन्य ऑब्जेक्ट्स संकलन समय पर जाने बिना भरोसा करते हैं कि उस कार्यक्षमता को प्रदान करने के लिए किस वर्ग का उपयोग किया जाएगा या बस किसी वस्तु को गुणों को इंजेक्ट करने के तरीके को निर्भरता इंजेक्शन कहा जाता है।

निर्भरता इंजेक्शन के लिए उदाहरण

पहले हम इस तरह कोड लिख रहे हैं

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

निर्भरता इंजेक्शन के साथ, निर्भरता इंजेक्टर हमारे लिए तात्कालिकता को हटा देगा

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

आप भी पढ़ सकते हैं

नियंत्रण और निर्भरता इंजेक्शन के व्युत्क्रम के बीच अंतर


17

निर्भरता इंजेक्शन क्या है?

डिपेंडेंसी इंजेक्शन (DI) का मतलब उन वस्तुओं को हटाना है जो एक-दूसरे पर निर्भर हैं। ऑब्जेक्ट ए कहो ऑब्जेक्ट बी पर निर्भर है इसलिए विचार एक दूसरे से इन ऑब्जेक्ट को हटाने के लिए है। हमें संकलन समय के बावजूद रनटाइम पर ऑब्जेक्ट्स पर निर्भरता साझा करने के बजाय नए कीवर्ड का उपयोग करके ऑब्जेक्ट को हार्ड कोड करने की आवश्यकता नहीं है। अगर हम बात करते हैं

वसंत में निर्भरता इंजेक्शन कैसे काम करता है:

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

नियंत्रण का उलटा (IOC)

आईओसी एक सामान्य अवधारणा है और इसे कई अलग-अलग तरीकों से व्यक्त किया जा सकता है और डिपेंडेंसी इंजेक्शन आईओसी का एक ठोस उदाहरण है।

निर्भरता इंजेक्शन के दो प्रकार:

  1. कंस्ट्रक्टर इंजेक्शन
  2. सेटर इंजेक्शन

1. कंस्ट्रक्टर-आधारित निर्भरता इंजेक्शन:

कंस्ट्रक्टर-आधारित DI को तब पूरा किया जाता है जब कंटेनर एक क्लास कंस्ट्रक्टर को कई तर्कों के साथ आमंत्रित करता है, प्रत्येक दूसरे वर्ग पर निर्भरता का प्रतिनिधित्व करता है।

public class Triangle {

private String type;

public String getType(){
    return type;
 }

public Triangle(String type){   //constructor injection
    this.type=type;
 }
}
<bean id=triangle" class ="com.test.dependencyInjection.Triangle">
        <constructor-arg value="20"/>
  </bean>

2. सेटर-आधारित निर्भरता इंजेक्शन:

सेटर-आधारित DI आपके सेम पर तत्काल तर्क निर्माता या नो-तर्क स्टैटिक फ़ैक्टरी विधि को लागू करने के बाद आपकी सेम पर सेटर कॉलिंग विधियों द्वारा पूरा किया जाता है।

public class Triangle{

 private String type;

 public String getType(){
    return type;
  }
 public void setType(String type){          //setter injection
    this.type = type;
  }
 }

<!-- setter injection -->
 <bean id="triangle" class="com.test.dependencyInjection.Triangle">
        <property name="type" value="equivialteral"/>

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


15

सबसे अच्छा सादृश्य मैं सोच सकता हूं कि ऑपरेशन थियेटर में सर्जन और उसके सहायक हैं, जहां सर्जन मुख्य व्यक्ति और उसका सहायक होता है, जो जरूरत पड़ने पर विभिन्न सर्जिकल घटकों को प्रदान करता है ताकि सर्जन एक पर ध्यान केंद्रित कर सके। वह सबसे अच्छा (सर्जरी) करता है। सहायक के बिना सर्जन को हर बार खुद को घटकों की आवश्यकता होती है।

डि फॉर शॉर्ट, आश्रित घटकों को लाने के लिए घटकों पर एक सामान्य अतिरिक्त जिम्मेदारी (बोझ) को हटाने की एक तकनीक है, उन्हें प्रदान करके।

DI आपको एकल जिम्मेदारी (SR) सिद्धांत के करीब लाता है, जैसे surgeon who can concentrate on surgery

DI का उपयोग कब करें: मैं लगभग सभी उत्पादन परियोजनाओं (छोटे / बड़े) में DI का उपयोग करने की सलाह दूंगा, विशेष रूप से कभी बदलते कारोबारी माहौल में :)

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


@IndRider धन्यवाद। मैं और अधिक सहमत नहीं हो सकता। मानव जीवन और मानव शरीर डिजाइन उत्कृष्टता के शानदार उदाहरण हैं। रीढ़ ईएसबी का एक उत्कृष्ट उदाहरण है:) ...
अनवर हुसैन

15

उदाहरण के लिए, हमारे पास 2 वर्ग Clientऔर हैं ServiceClientउपयोग होगाService

public class Service {
    public void doSomeThingInService() {
        // ...
    }
}

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

रास्ता 1)

public class Client {
    public void doSomeThingInClient() {
        Service service = new Service();
        service.doSomeThingInService();
    }
}

रास्ता 2)

public class Client {
    Service service = new Service();
    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

रास्ता 3)

public class Client {
    Service service;
    public Client() {
        service = new Service();
    }
    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

1) 2) 3) का उपयोग करना

Client client = new Client();
client.doSomeThingInService();

लाभ

  • सरल

नुकसान

  • टेस्ट Clientक्लास के लिए कठिन
  • जब हम Serviceकंस्ट्रक्टर बदलते हैं , तो हमें Serviceऑब्जेक्ट बनाने के लिए सभी जगह कोड बदलने की आवश्यकता होती है

डिपेंडेंसी इंजेक्शन का प्रयोग करें

तरीका 1) कंस्ट्रक्टर इंजेक्शन

public class Client {
    Service service;

    Client(Service service) {
        this.service = service;
    }

    // Example Client has 2 dependency 
    // Client(Service service, IDatabas database) {
    //    this.service = service;
    //    this.database = database;
    // }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

का उपयोग करते हुए

Client client = new Client(new Service());
// Client client = new Client(new Service(), new SqliteDatabase());
client.doSomeThingInClient();

तरीका 2) सेटर इंजेक्शन

public class Client {
    Service service;

    public void setService(Service service) {
        this.service = service;
    }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

का उपयोग करते हुए

Client client = new Client();
client.setService(new Service());
client.doSomeThingInClient();

रास्ता 3) इंटरफ़ेस इंजेक्शन

Https://en.wikipedia.org/wiki/D dependency_injection जांचें

===

अब, यह कोड पहले से ही अनुसरण कर रहा है Dependency Injectionऔर परीक्षण Clientवर्ग के लिए आसान है ।
हालांकि, हम अभी भी new Service()कई समय का उपयोग करते हैं और यह अच्छा नहीं है जब Serviceनिर्माणकर्ता बदलता है । इसे रोकने के लिए, हम
1) सरल मैनुअल की तरह DI इंजेक्टर का उपयोग कर सकते हैंInjector

public class Injector {
    public static Service provideService(){
        return new Service();
    }

    public static IDatabase provideDatatBase(){
        return new SqliteDatabase();
    }
    public static ObjectA provideObjectA(){
        return new ObjectA(provideService(...));
    }
}

का उपयोग करते हुए

Service service = Injector.provideService();

2) लाइब्रेरी का उपयोग करें: Android dagger2 के लिए

लाभ

  • परीक्षा को आसान बनाएं
  • जब आप इसे बदलते हैं Service, तो आपको इसे इंजेक्टर क्लास में बदलने की आवश्यकता होती है
  • यदि आप उपयोग करते हैं Constructor Injection, तो जब आप कंस्ट्रक्टर Clientको देखते हैं, तो आप देखेंगे कि Clientकक्षा की निर्भरता कितनी है

नुकसान

  • यदि आप उपयोग का उपयोग करते हैं Constructor Injection, तो Serviceऑब्जेक्ट तब Clientबनाया जाता है जब बनाया जाता है, कभी-कभी हम Clientक्लास में फ़ंक्शन का उपयोग करते हैं Serviceताकि बनाया गया उपयोग Serviceबर्बाद न हो

निर्भरता इंजेक्शन परिभाषा

https://en.wikipedia.org/wiki/Dependency_injection

एक निर्भरता एक ऐसी वस्तु है जिसका इस्तेमाल किया जा सकता है ( Service)
एक इंजेक्शन Serviceएक निर्भर वस्तु ( Client) के लिए एक निर्भरता ( ) का गुजरना है जो इसे बढ़ाएगा।


13

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

"डिपेंडेंसी इंजेक्शन" (DI) को "इनवर्सन ऑफ कंट्रोल" (IoC) के रूप में भी जाना जाता है, इस ढीले युग्मन को प्रोत्साहित करने के लिए एक तकनीक के रूप में इस्तेमाल किया जा सकता है।

DI को लागू करने के लिए दो प्राथमिक दृष्टिकोण हैं:

  1. कंस्ट्रक्टर इंजेक्शन
  2. सेटर इंजेक्शन

कंस्ट्रक्टर इंजेक्शन

यह वस्तुओं की निर्भरता के निर्माण की तकनीक है।

ध्यान दें कि कंस्ट्रक्टर एक इंटरफ़ेस स्वीकार करता है न कि ठोस वस्तु। इसके अलावा, ध्यान दें कि एक अपवाद फेंक दिया जाता है यदि ऑर्डरडाउ पैरामीटर शून्य है। यह एक वैध निर्भरता प्राप्त करने के महत्व पर जोर देता है। कंस्ट्रक्टर इंजेक्शन, मेरी राय में, किसी वस्तु को उसकी निर्भरता देने के लिए पसंदीदा तंत्र है। डेवलपर को यह स्पष्ट है कि जिस वस्तु पर निर्भरता की जरूरत है उसे उचित निष्पादन के लिए "व्यक्ति" को दिया जाए।

सेटर इंजेक्शन

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

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

  1. एक विरासत वर्ग के निर्माता को संशोधित किए बिना निर्भरता इंजेक्शन का समर्थन करना।
  2. महंगे संसाधनों या सेवाओं को संभव के रूप में देर से और आवश्यक होने पर ही बनाया जाना है।

यहाँ उदाहरण है कि उपरोक्त कोड कैसा दिखेगा:

public class Person {
    public Person() {}

    public IDAO Address {
        set { addressdao = value; }
        get {
            if (addressdao == null)
              throw new MemberAccessException("addressdao" +
                             " has not been initialized");
            return addressdao;
        }
    }

    public Address GetAddress() {
       // ... code that uses the addressdao object
       // to fetch address details from the datasource ...
    }

    // Should not be called directly;
    // use the public property instead
    private IDAO addressdao;

3
मुझे लगता है कि आपका पहला पैराग्राफ प्रश्न से दूर है, और DI की परिभाषा में नहीं है (यानी, आप SOLID को परिभाषित करने की कोशिश कर रहे हैं, DI नहीं)। तकनीकी रूप से, भले ही आपके पास 100 निर्भरताएं हों, फिर भी आप निर्भरता इंजेक्शन का उपयोग कर सकते हैं। इसी तरह, कंक्रीट निर्भरता को इंजेक्ट करना संभव है - यह अभी भी निर्भरता इंजेक्शन है।
जय सुलिवन

10

मुझे लगता है कि जब से सभी ने DI के लिए लिखा है, मुझे कुछ सवाल पूछने दो।

  1. जब आपके पास DI का एक कॉन्फ़िगरेशन होता है, जहां सभी वास्तविक कार्यान्वयन (इंटरफेस नहीं) होते हैं जो एक वर्ग में इंजेक्ट किए जाते हैं (उदाहरण के लिए एक नियंत्रक के लिए सेवाएं) तो यह किसी प्रकार का हार्ड-कोडिंग क्यों नहीं है?
  2. अगर मैं रनटाइम में ऑब्जेक्ट को बदलना चाहता हूं तो क्या होगा? उदाहरण के लिए, मेरा कॉन्फिगरेशन पहले से ही कहता है जब मैं MyController इंस्टेंट करता हूं, तो ILogger के रूप में FileLogger के लिए इंजेक्ट करें। लेकिन मैं DatabaseLogger इंजेक्षन करना चाहते हो सकता है।
  3. हर बार मैं बदलना चाहता हूं कि मेरे एसीलैस को किन चीजों की जरूरत है, मुझे अब दो जगहों पर देखने की जरूरत है- क्लास खुद और कॉन्फ़िगरेशन फाइल। यह कैसे जीवन को आसान बनाता है?
  4. यदि AClass की Aproperty को इंजेक्ट नहीं किया जाता है, तो क्या इसका मजाक उड़ाना कठिन है?
  5. पहले सवाल पर वापस जाना। यदि नई वस्तु () का उपयोग करना खराब है, तो हम कार्यान्वयन को कैसे इंजेक्ट करेंगे और इंटरफ़ेस को नहीं? मुझे लगता है कि आप बहुत से कह रहे हैं कि हम वास्तव में इंटरफ़ेस को इंजेक्ट कर रहे हैं, लेकिन कॉन्फ़िगरेशन आपको उस इंटरफ़ेस के कार्यान्वयन को निर्दिष्ट करता है .. रनटाइम के दौरान नहीं। यह संकलन समय के दौरान हार्डकोड है।

यह @Adam N पोस्ट किए गए जवाब पर आधारित है।

क्यों PersonalService को अब GroupMembershipService के बारे में चिंता करने की ज़रूरत नहीं है? आपने अभी उल्लेख किया है GroupMembership में कई चीजें (ऑब्जेक्ट्स / प्रॉपर्टीज़) हैं जो इस पर निर्भर करती हैं। यदि PSMS में GMService की आवश्यकता थी, तो आपके पास यह एक संपत्ति के रूप में होगा। आप इस बात का ध्यान रख सकते हैं कि आपने इसे इंजेक्ट किया है या नहीं। केवल एक बार मैं चाहूंगा कि इसे इंजेक्ट किया जाए अगर GMService में अधिक विशिष्ट बाल कक्षाएं थीं, जिन्हें आप रनटाइम तक नहीं जानते होंगे। फिर आप उपवर्ग को इंजेक्ट करना चाहेंगे। या यदि आप इसे एकल या प्रोटोटाइप के रूप में उपयोग करना चाहते हैं। ईमानदार होने के लिए, कॉन्फ़िगरेशन फ़ाइल में सब कुछ हार्डकोड किया गया है जहां तक ​​कि एक प्रकार (इंटरफ़ेस) के लिए उपवर्ग क्या है जो संकलन समय के दौरान इंजेक्ट करने जा रहा है।

संपादित करें

DI पर जोस मारिया अरेंज द्वारा एक अच्छी टिप्पणी

DI निर्भरता की दिशा निर्धारित करने और किसी भी गोंद कोड को लिखने की आवश्यकता को हटाकर सामंजस्य बढ़ाता है।

असत्य। निर्भरता की दिशा XML रूप में या एनोटेशन के रूप में है, आपकी निर्भरता XML कोड और एनोटेशन के रूप में लिखी जाती है। XML और एनोटेशन स्रोत कोड हैं।

DI आपके सभी घटकों को मॉड्यूलर बना देता है (यानी बदली) और एक-दूसरे के लिए अच्छी तरह से परिभाषित इंटरफेस है।

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

बदली के बारे में: एक बहुत ही सरल .प्राय संग्रह और Class.forName से आप परिभाषित कर सकते हैं कि कौन सी कक्षाएं बदल सकती हैं। यदि आपके कोड के किसी भी वर्ग को बदला जा सकता है, तो जावा आपके लिए नहीं है, एक स्क्रिप्टिंग भाषा का उपयोग करें। वैसे: एनोटेशन को फिर से देखे बिना बदला नहीं जा सकता है।

मेरी राय में डीआई फ्रेमवर्क का एक ही कारण है: बॉयलर प्लेट की कमी। एक अच्छी तरह से किए गए कारखाने प्रणाली के साथ आप अपने पसंदीदा DI ढांचे के रूप में एक ही, अधिक नियंत्रित और अधिक अनुमानित कर सकते हैं, DI चौखटे कोड में कमी का वादा करते हैं (XML और एनोटेशन स्रोत कोड भी हैं)। समस्या यह है कि बॉयलर प्लेट की कमी बहुत ही सरल मामलों (एक उदाहरण-प्रति वर्ग और समान) में वास्तविक है, कभी-कभी वास्तविक दुनिया में विनियोजित सेवा ऑब्जेक्ट को उठाते हुए एक सिंगलटन ऑब्जेक्ट के लिए एक वर्ग को मैप करना उतना आसान नहीं है।


8

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

$foo = Foo->new($bar);

हम बस उस पासिंग पैरामीटर को कंस्ट्रक्टर में कहते हैं। हम ऐसा नियमित रूप से कर रहे हैं जब से निर्माणकर्ताओं का आविष्कार किया गया था।

"निर्भरता इंजेक्शन" को "नियंत्रण का व्युत्क्रम" का एक प्रकार माना जाता है, जिसका अर्थ है कि कॉल करने वाले से कुछ तर्क लिया जाता है। ऐसा नहीं है जब कॉलर मापदंडों में गुजरता है, इसलिए यदि वह DI, DI होता तो नियंत्रण का उलटा नहीं होता।

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

gcc -c foo.cpp; gcc -c bar.cpp

करने से पहले

gcc foo.o bar.o -o bar

"बार बनाएं" टाइप करने वाले व्यक्ति को यह जानने की आवश्यकता नहीं है कि बार फू पर निर्भर करता है। निर्भरता "मेक बार" और gcc के बीच इंजेक्ट की गई थी।

मध्यवर्ती स्तर का मुख्य उद्देश्य केवल निर्माणकर्ता के लिए निर्भरता में पारित करना नहीं है, बल्कि सभी निर्भरताओं को केवल एक स्थान पर सूचीबद्ध करना है , और उन्हें कोडर से छुपाना है (कोडर प्रदान करने के लिए नहीं)।

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


8

निर्भरता इंजेक्शन का मतलब कोड के एक हिस्से के लिए एक तरह से (वास्तव में किसी भी तरह से ) है (जैसे एक वर्ग) निर्भरता (कोड के अन्य भागों, अन्य वर्गों, जैसे यह निर्भर करता है) तक पहुंच के लिए एक मॉड्यूलर तरीके से उनके बिना हार्डकोड किया जा रहा है (इसलिए वे स्वतंत्र रूप से बदल सकते हैं या स्वतंत्र रूप से ओवरराइड कर सकते हैं, या यहां तक ​​कि जरूरत के अनुसार लोड हो सकते हैं)

(और पीएस, हाँ यह एक सरल, अवधारणा के लिए अति-सम्मोहित 25 $ का नाम बन गया है) , मेरे .25सेंट


8

मैं जानता हूँ कि पहले से ही कई सवालों के जवाब नहीं है, लेकिन मैं यह बहुत ही उपयोगी पाया: http://tutorials.jenkov.com/dependency-injection/index.html

कोई निर्भरता नहीं:

public class MyDao {

  protected DataSource dataSource = new DataSourceImpl(
    "driver", "url", "user", "password");

  //data access methods...
  public Person readPerson(int primaryKey) {...}     
}

निर्भरता:

public class MyDao {

  protected DataSource dataSource = null;

  public MyDao(String driver, String url, String user, String password) {
    this.dataSource = new DataSourceImpl(driver, url, user, password);
  }

  //data access methods...
  public Person readPerson(int primaryKey) {...}
}

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


1
क्या आप पहले से निर्मित अपने DataSourceImp को इंटरफ़ेस द्वारा पारित नहीं करेंगे?
पमनस

6

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

दुर्भाग्य से बुरा हिस्सा यह है कि कुछ लोगों ने मान लिया है कि आपको एक विशेष ढाँचे की ज़रूरत है ताकि आप निर्भरता को कम कर सकें और अगर आप इसे करने के लिए किसी विशेष ढांचे का उपयोग नहीं करने का विकल्प चुनते हैं तो आप किसी 'कम' प्रोग्रामर हैं। एक और, बहुत परेशान करने वाला मिथक, कई लोगों द्वारा माना जाता है, कि निर्भरता इंजेक्शन केवल निर्भरता प्राप्त करने का एकमात्र तरीका है। यह प्रदर्शन और ऐतिहासिक रूप से और स्पष्ट रूप से 100% गलत है, लेकिन आपको कुछ लोगों को यह समझाने में परेशानी होगी कि आपकी निर्भरता की आवश्यकताओं के लिए निर्भरता इंजेक्शन के विकल्प हैं।

प्रोग्रामर ने वर्षों के लिए निर्भरता की आवश्यकता को समझ लिया है और निर्भरता इंजेक्शन के पहले और बाद में कई वैकल्पिक समाधान विकसित हुए हैं। वहाँ फैक्टरी पैटर्न रहे हैं, लेकिन वहाँ भी कई विकल्प ThreadLocal का उपयोग कर जहां एक विशेष उदाहरण के लिए कोई इंजेक्शन की जरूरत है कर रहे हैं - के लिए निर्भरता को प्रभावी ढंग से धागा जो (सुविधा के स्थिर गेटर विधियों के माध्यम से) वस्तु उपलब्ध बनाने को लाभ मिलता है में इंजेक्ट किया जाता है किसी भीजिस वर्ग को इसकी आवश्यकता होती है, उस वर्ग के एनोटेशन को जोड़ने की आवश्यकता नहीं होती है और इसे बनाने के लिए जटिल XML 'गोंद' सेट करता है। जब आपकी निर्भरता दृढ़ता (जेपीए / जेडीओ या जो भी हो) के लिए आवश्यक होती है, तो यह आपको 'ट्रांसपैरेंट दृढ़ता' को प्राप्त करने की अनुमति देता है और डोमेन मॉडल और बिजनेस मॉडल कक्षाओं के साथ पूरी तरह से पीओजेओ (अर्थात कोई रूपरेखा विशिष्ट नहीं होती है)।


5

बुक से, ' वेल-ग्राउंडेड जावा डेवलपर: जावा 7 की महत्वपूर्ण तकनीक और पॉलीग्लॉट प्रोग्रामिंग

DI आईओसी का एक विशेष रूप है, जिससे आपकी निर्भरता खोजने की प्रक्रिया आपके वर्तमान में निष्पादित कोड के प्रत्यक्ष नियंत्रण से बाहर है।


5

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

पहली तस्वीर में, मान लें कि आपके पास बहुत सारे एकजुट होने के साथ एक कार कारखाना है । एक कार वास्तव में असेंबली यूनिट में बनाई गई है, लेकिन इसमें इंजन , सीटों के साथ-साथ पहियों की भी जरूरत होती है । इसलिए विधानसभा इकाई इन सभी इकाइयों पर निर्भर है और वे कारखाने के आश्रित हैं ।

आप महसूस कर सकते हैं कि अब इस कारखाने में सभी कार्यों को बनाए रखना बहुत जटिल है क्योंकि मुख्य कार्य (असेंबली यूनिट में असेंबलिंग कार) के साथ-साथ आपको अन्य इकाइयों पर भी ध्यान केंद्रित करना होगा । अब इसे बनाए रखना बहुत महंगा है और कारखाने की इमारत बहुत बड़ी है इसलिए यह किराए के लिए आपके अतिरिक्त रुपये लेता है।

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

अब हम कह सकते हैं कि कार को असेंबल करने के लिए सभी निर्भरताएं प्रदाताओं से कारखाने पर इंजेक्ट की जाती हैं । यह वास्तविक जीवन पर निर्भरता इंजेक्शन (DI) का एक उदाहरण है ।

अब तकनीकी शब्द में, निर्भरता इंजेक्शन एक ऐसी तकनीक है जिसके तहत एक वस्तु (या स्थिर विधि) किसी अन्य वस्तु की निर्भरता की आपूर्ति करती है। तो, किसी और को वस्तु बनाने के कार्य को स्थानांतरित करना और सीधे निर्भरता का उपयोग करना निर्भरता इंजेक्शन कहलाता है।

यह अब आपको कुछ तकनीकी शब्द के साथ DI सीखने में मदद करेगा। यह दिखाएगा कि डि का उपयोग कब करना चाहिए और कब नहीं करना चाहिए ।

सभी एक कार कारखाने में

साधारण कार का कारखाना


1
40 ईश में से सबसे स्पष्ट उत्तर। वास्तविक जीवन का उदाहरण और चित्र। +1। स्वीकृत उत्तर होना चाहिए।
मार्च रेमी

4

बुक अप्रेस से। Spring.Persistence.with.Hibernate.Oct.2010

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


4

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

पुस्तक का इंटरफ़ेस:

package com.deepam.hidden;

public interface BookInterface {

public BookInterface setHeight(int height);
public BookInterface setPages(int pages);   
public int getHeight();
public int getPages();  

public String toString();
}

आगे हमारे पास कई तरह की किताबें हो सकती हैं; एक प्रकार फिक्शन है:

package com.deepam.hidden;

public class FictionBook implements BookInterface {
int height = 0; // height in cm
int pages = 0; // number of pages

/** constructor */
public FictionBook() {
    // TODO Auto-generated constructor stub
}

@Override
public FictionBook setHeight(int height) {
  this.height = height;
  return this;
}

@Override
public FictionBook setPages(int pages) {
  this.pages = pages;
  return this;      
}

@Override
public int getHeight() {
    // TODO Auto-generated method stub
    return height;
}

@Override
public int getPages() {
    // TODO Auto-generated method stub
    return pages;
}

@Override
public String toString(){
    return ("height: " + height + ", " + "pages: " + pages);
}
}

अब ग्राहक की पुस्तक से जुड़ाव हो सकता है:

package com.deepam.hidden;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Subscriber {
BookInterface book;

/** constructor*/
public Subscriber() {
    // TODO Auto-generated constructor stub
}

// injection I
public void setBook(BookInterface book) {
    this.book = book;
}

// injection II
public BookInterface setBook(String bookName) {
    try {
        Class<?> cl = Class.forName(bookName);
        Constructor<?> constructor = cl.getConstructor(); // use it for parameters in constructor
        BookInterface book = (BookInterface) constructor.newInstance();
        //book = (BookInterface) Class.forName(bookName).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return book;
}

public BookInterface getBook() {
  return book;
}

public static void main(String[] args) {

}

}

इसके कार्यान्वयन के लिए सभी तीन वर्गों को छिपाया जा सकता है। अब हम DI के लिए इस कोड का उपयोग कर सकते हैं:

package com.deepam.implement;

import com.deepam.hidden.Subscriber;
import com.deepam.hidden.FictionBook;

public class CallHiddenImplBook {

public CallHiddenImplBook() {
    // TODO Auto-generated constructor stub
}

public void doIt() {
    Subscriber ab = new Subscriber();

    // injection I
    FictionBook bookI = new FictionBook();
    bookI.setHeight(30); // cm
    bookI.setPages(250);
    ab.setBook(bookI); // inject
    System.out.println("injection I " + ab.getBook().toString());

    // injection II
    FictionBook bookII = ((FictionBook) ab.setBook("com.deepam.hidden.FictionBook")).setHeight(5).setPages(108); // inject and set
    System.out.println("injection II " + ab.getBook().toString());      
}

public static void main(String[] args) {
    CallHiddenImplBook kh = new CallHiddenImplBook();
    kh.doIt();
}
}

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


4

5 साल के बच्चों के लिए निर्भरता इंजेक्शन।

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

आप जो कर रहे हैं वह एक ज़रूरत बता रही है, "मुझे दोपहर के भोजन के साथ पीने के लिए कुछ चाहिए" और फिर हम यह सुनिश्चित करेंगे कि जब आप खाने के लिए बैठें तो आपके पास कुछ हो।


1
यह स्पष्ट रूप से माता-पिता का जवाब है। ;)
मार्च रेमी

4

क्रिस्टोफर नॉरिंग से, पाब्लो डेलेमैन की पुस्तक "लर्निंग एंगुलर - दूसरा संस्करण":

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

प्रेषक: एंटोन मोइसेव पुस्तक "टाइपस्क्रिप्ट के साथ कोणीय विकास, दूसरा संस्करण।":

"संक्षेप में, DI आपको शिथिल युग्मित तरीके से कोड लिखने में मदद करता है और आपके कोड को अधिक परीक्षण योग्य और पुन: प्रयोज्य बनाता है ।"


3

सरल शब्दों में निर्भरता इंजेक्शन (DI) विभिन्न वस्तुओं के बीच निर्भरता या तंग युग्मन को हटाने का तरीका है। डिपेंडेंसी इंजेक्शन प्रत्येक वस्तु के लिए एक सुसंगत व्यवहार देता है।

DI वसंत के IOC प्रमुख का कार्यान्वयन है जो कहता है कि "हमें कॉल न करें हम आपको कॉल करेंगे"। निर्भरता इंजेक्शन प्रोग्रामर का उपयोग करके नए कीवर्ड का उपयोग करके ऑब्जेक्ट बनाने की आवश्यकता नहीं है।

ऑब्जेक्ट्स को एक बार स्प्रिंग कंटेनर में लोड कर दिया जाता है और फिर हम उन्हें दोबारा इस्तेमाल करते हैं, जब भी हमें स्प्रिंगबिन (स्ट्रिंग बीननाम) विधि का उपयोग करके स्प्रिंग कंटेनर से उन वस्तुओं को प्राप्त करने की आवश्यकता होती है।


3

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

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

डिप्‍जेन्‍सी इंसपिरेशन सिम्यूलिंग ग्लूइंग क्‍वॉसेस है और इस सेशन के दौरान एक ही समय पर।

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