निर्भरता इंजेक्शन की शैलियों के बीच व्यावहारिक अंतर क्या है?


12

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

यह मुझे लगता है कि एक के बाद एक का उपयोग करने के लिए कारण कोड सफाई और / या स्पष्टता की बात है। अंतर क्या है? क्या किसी एक के ऊपर एक उपयोग करने के कोई मजबूत फायदे या नुकसान हैं, या क्या यह वही है जो मैंने पहले कहा है?

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


निश्चित नहीं है कि आपने और क्या पाया है या रास्ते में पढ़ा है। मुझे यहां और यहां कुछ इसी तरह के धागे मिले । मैं खुद नया हूँ, और आपके उत्तर के लिए उत्सुक

@ user1766760 आपको मेरी मदद करनी चाहिए फिर यहाँ, मेरे सवाल को बंद करने के लिए मतदान किया जा रहा है, दो और वोट और यह हो गया !!! सवाल उठाइए या कुछ और, मैं नहीं जानता कि समापन से बचने के लिए क्या किया जा सकता है।
इकोम्पावर

erm ... मैं खुद SO के लिए नया हूं इसलिए मुझे यकीन नहीं है कि मैं कैसे मदद कर सकता हूं / इसे बंद करने के लिए मतदान क्यों किया जा रहा है (मुझे कोई संकेत नहीं दिखता है?)। अगर मैं एक अनुमान लगाता हूं, तो शायद यह एक विशिष्ट प्रोग्रामिंग प्रश्न नहीं है, लेकिन चर्चा का अधिक है?

आप प्रश्न को थोड़ा विस्तार देना पसंद कर सकते हैं। निर्भरता इंजेक्शन "उलटा नियंत्रण" का एक रूप है। विकल्प हैं। दुरुपयोग के विकल्प के लिए एक उपयोगी लेकिन पका हुआ उदाहरण के लिए सेवा स्थान है।
इयान

जवाबों:


12

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

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

इंटरफ़ेस इंजेक्शन , जहां तक ​​मैं बता सकता हूं, सेटर इंजेक्शन से बहुत अलग नहीं है। दोनों मामलों में आप (वैकल्पिक रूप से) एक निर्भरता की स्थापना कर रहे हैं जिसे बाद में बदला जा सकता है।

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

अक्सर बार, दो अलग-अलग कार्यान्वयन में पारित करने के लिए मेरा एकमात्र कारण परीक्षण के लिए है। उत्पादन में, मैं एक में पास हो सकता हूं DataRepository, लेकिन परीक्षण में, मैं एक में गुजरता हूं FakeDataRepository। इस मामले में मैं आमतौर पर दो निर्माणकर्ता प्रदान करूंगा: एक जिसमें कोई पैरामीटर नहीं है, और दूसरा जो स्वीकार करता है a IDataRepository। फिर, बिना किसी पैरामीटर वाले कंस्ट्रक्टर में, मैं दूसरे कंस्ट्रक्टर को कॉल चेन करूंगा और पास करूंगा new DataRepository()

यहाँ C # में एक उदाहरण दिया गया है:


public class Foo
{
  private readonly IDataRepository dataRepository;

  public Foo() : this(new DataRepository())
  {
  }

  public Foo(IDataRespository dataRepository)
  {
    this.dataRepository = dataRepository;
  }
}

यह गरीब आदमी की निर्भरता इंजेक्शन के रूप में जाना जाता है। मुझे यह पसंद है क्योंकि उत्पादन ग्राहक कोड में, मुझे कई दोहराए गए बयानों को देखने की आवश्यकता नहीं है

var foo = new Foo(new DataRepository());
हालाँकि, मैं अभी भी परीक्षण के लिए एक वैकल्पिक कार्यान्वयन में पारित कर सकता हूं। मुझे एहसास है कि गरीब आदमी के डीआई के साथ मैं अपनी निर्भरता को हार्डकोड कर रहा हूं, लेकिन यह मेरे लिए स्वीकार्य है क्योंकि मैं ज्यादातर परीक्षण के लिए डीआई का उपयोग करता हूं।


धन्यवाद, यह काफी कुछ है जो मैं समझता हूं, लेकिन फिर भी, क्या कोई ऐसा परिदृश्य है जहां आप कंस्ट्रक्टर इंजेक्शन का उपयोग नहीं कर सकते हैं ?
इम्पैम्पर

1
आप संभवतः वैकल्पिक निर्भरता के लिए निर्माता इंजेक्शन का उपयोग नहीं करना चाहेंगे। मैं इसका उपयोग नहीं करने के लिए कोई अन्य कारण नहीं सोच सकता।
जवलेट

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

@ जलेटलेट - यह शानदार है, मैं यूनिट परीक्षण के लिए एक अच्छा सरल स्टबिंग तकनीक की तलाश में हूं जो मेरे समाधान को जटिल नहीं करता है - और मुझे लगता है कि यह है :)
रॉकलैन

2

कंस्ट्रक्टर और सेटर इंजेक्शन के बीच अंतर पहले से ही पर्याप्त रूप से ऊपर वर्णित हैं, इसलिए मैं उन पर आगे विस्तार नहीं करूंगा।

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

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

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

  • यह निर्भर करता है कि कैश्ड कॉपी से लोड होने पर वे मौजूद हैं या जब वे नहीं करते हैं (जैसे SoftReferenceजावा में एक का उपयोग करके ) पुनर्निवेश।

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

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