निर्भरता इंजेक्शन ढांचे के लिए तर्क में से एक पर सवाल: क्यों एक वस्तु ग्राफ मुश्किल बना रहा है?


13

Google Guice जैसी निर्भरता इंजेक्शन ढाँचे उनके उपयोग ( स्रोत ) के लिए निम्नलिखित प्रेरणा देते हैं :

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

हाथ से ऑब्जेक्ट ग्राफ़ बनाना श्रम गहन (...) है और परीक्षण को कठिन बनाता है।

लेकिन मैं इस तर्क को नहीं खरीदता: यहां तक ​​कि एक निर्भरता इंजेक्शन ढांचे के बिना, मैं उन कक्षाओं को लिख सकता हूं जो परीक्षण के लिए आसान और सुविधाजनक दोनों हैं। उदाहरण के लिए गुइस प्रेरणा पृष्ठ से उदाहरण निम्नलिखित तरीके से लिखे जा सकते हैं:

class BillingService
{
    private final CreditCardProcessor processor;
    private final TransactionLog transactionLog;

    // constructor for tests, taking all collaborators as parameters
    BillingService(CreditCardProcessor processor, TransactionLog transactionLog)
    {
        this.processor = processor;
        this.transactionLog = transactionLog;
    }

    // constructor for production, calling the (productive) constructors of the collaborators
    public BillingService()
    {
        this(new PaypalCreditCardProcessor(), new DatabaseTransactionLog());
    }

    public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard)
    {
        ...
    }
}

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


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

ध्यान दें कि मैं निर्भरता इंजेक्शन के अन्य लाभों की तलाश नहीं कर रहा हूं - मैं केवल इस तर्क को समझने में दिलचस्पी रखता हूं कि "निर्भरता इंजेक्शन के बिना ऑब्जेक्ट
इंस्टेंटेशन

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

@ इज़काटा नहीं, यह आकार का मामला नहीं है। वर्णित दृष्टिकोण के साथ, उस पोस्ट का कोड बस होगा new ShippingService()
oberlies

@ रॉबर्ट्स स्टिल है; फिर आपको 9 कक्षा परिभाषाओं में खुदाई करनी होगी ताकि यह पता लगाया जा सके कि कौन सी कक्षाएं उस शिपिंग सेवा के लिए उपयोग की जा रही हैं, बजाय एक स्थान पर
इज़काता

जवाबों:


12

निर्भरता इंजेक्शन करने के सर्वोत्तम तरीके के बारे में एक पुरानी, ​​पुरानी चल रही बहस है।

  • वसंत की मूल कटौती ने एक सादे वस्तु को बदल दिया, और फिर सेटर विधियों के बावजूद निर्भरता को इंजेक्ट किया।

  • लेकिन तब लोगों की एक बड़ी आकस्मिकता ने जोर देकर कहा कि कंस्ट्रक्टर मापदंडों के माध्यम से निर्भरता को इंजेक्शन करना सही तरीका था।

  • फिर, हाल ही में, जैसा कि प्रतिबिंब का उपयोग करना अधिक सामान्य हो गया, निजी सदस्यों के मूल्यों को सीधे स्थापित करना, बिना बसने या निर्माण करने वाले आर्ग के बिना, क्रोध बन गया।

तो आपका पहला कंस्ट्रक्टर निर्भरता इंजेक्शन के दूसरे दृष्टिकोण के अनुरूप है। यह आपको परीक्षण के लिए इंजेक्शन मॉक जैसी अच्छी चीजें करने की अनुमति देता है।

लेकिन नो-लॉजिक कंस्ट्रक्टर को यह समस्या है। चूंकि यह कार्यान्वयन कक्षाओं के लिए तात्कालिक है PaypalCreditCardProcessorऔर DatabaseTransactionLog, यह पेपाल और डेटाबेस पर एक कठिन, संकलन-समय निर्भरता बनाता है। यह उस संपूर्ण निर्भरता के पेड़ को सही ढंग से बनाने और कॉन्फ़िगर करने की जिम्मेदारी लेता है।

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

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

  • तात्कालिकता के अलावा, प्रत्येक ऑब्जेक्ट को कॉन्फ़िगरेशन से लागू किए गए गुणों की आवश्यकता होगी।

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

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

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

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

...

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

यह चिंता का अलगाव प्रदान करता है ताकि मेरी कक्षा बस यह काम कर सके, और फ़ैक्टरी वर्ग सामान बनाने और कॉन्फ़िगर करने की ज़िम्मेदारी लेता है।

आवश्यक दृष्टिकोण नहीं, लेकिन एफडब्ल्यूआईडब्ल्यू

...

आम तौर पर, डीआई / इंटरफ़ेस पैटर्न दो चीजों को करके आपके कोड की जटिलता को कम करता है:

  • अमूर्त डाउनस्ट्रीम निर्भरता इंटरफेस में

  • "लिफ्टिंग" अपने कोड से बाहर की निर्भरता और किसी प्रकार के कंटेनर में

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


कोड उस सभी के निर्माण की जिम्मेदारी ग्रहण करेगा - एक वर्ग केवल यह जानने की जिम्मेदारी लेता है कि उसके सहयोगी कार्यान्वयन क्या हैं। यह जानने की जरूरत नहीं है कि इन सहयोगियों को बदले में क्या चाहिए। तो यह उतना नहीं है।
oberlies

1
लेकिन अगर पेपालप्रोसेसर कंस्ट्रक्टर के पास 2 तर्क थे, तो वे कहां से आएंगे?
रोब

यह नहीं है बिलिंग सर्विस की तरह, पेपालप्रोसेसर में एक शून्य-आर्ग कंस्ट्रक्टर है जो सहयोगियों को इसकी आवश्यकता है।
oberlies

अमूर्त डाउनस्ट्रीम निर्भरता इंटरफेस में - उदाहरण कोड यह भी करता है। प्रोसेसर फ़ील्ड प्रकार CreditCardProcessor का है, न कि कार्यान्वयन प्रकार का।
oberlies

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

4
  1. जब आप पूल के उथले छोर पर तैरते हैं, तो सब कुछ "आसान और सुविधाजनक" होता है। एक बार जब आप एक दर्जन से अधिक वस्तुओं को पा लेते हैं, तो यह सुविधाजनक नहीं रह जाता है।
  2. आपके उदाहरण में, आपने अपनी बिलिंग प्रक्रिया को हमेशा के लिए और पेपाल को एक दिन के लिए बाध्य कर दिया है। मान लीजिए आप एक अलग क्रेडिट कार्ड प्रोसेसर का उपयोग करना चाहते हैं? मान लीजिए कि आप एक विशेष क्रेडिट कार्ड प्रोसेसर बनाना चाहते हैं जो नेटवर्क पर विवश है? या आपको क्रेडिट कार्ड नंबर हैंडलिंग का परीक्षण करने की आवश्यकता है? आपने गैर-पोर्टेबल कोड बनाया है: "एक बार लिखें, केवल एक बार उपयोग करें क्योंकि यह उस विशिष्ट ऑब्जेक्ट ग्राफ पर निर्भर करता है जिसके लिए इसे डिज़ाइन किया गया था।"

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

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


जब मैं आपके तर्क का पालन करता हूं, तो डीआई के लिए तर्क "हाथ से ऑब्जेक्ट ग्राफ बनाना आसान होना चाहिए था, लेकिन कोड की ओर जाता है कि इसे बनाए रखना मुश्किल है"। हालांकि दावा यह था कि "हाथ से ऑब्जेक्ट ग्राफ बनाना कठिन है" और मैं केवल उस दावे का समर्थन करने वाले तर्कों की तलाश कर रहा हूं। तो आपकी पोस्ट मेरे सवाल का जवाब नहीं देती।
22'14

1
मुझे लगता है कि यदि आप "बनाने के लिए प्रश्न को कम एक वस्तु ग्राफ ...", तो यह सरल है। मेरी बात यह है कि DI उस मुद्दे को संबोधित करता है जिसे आप कभी भी केवल एक ऑब्जेक्ट ग्राफ से नहीं निपटते हैं ; आप उनमें से एक परिवार के साथ व्यवहार करते हैं।
BobDalgleish


4

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

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


1
लेकिन निर्भरता पेड़ एक पेड़ होना चाहिए, ग्राफ सिद्धांत अर्थ में। अन्यथा आपको एक चक्र मिला है, जो केवल असंतोषजनक है।
Xion

1
@Xion निर्भरता ग्राफ एक निर्देशित चक्रीय ग्राफ होना चाहिए। कोई आवश्यकता नहीं है कि पेड़ों की तरह दो नोड्स के बीच केवल एक ही रास्ता है।
22'14

@ एक्सियन: जरूरी नहीं। एक विचार के UnitOfWorkजो एक विलक्षण है DbContextऔर कई खजाने। इन सभी रिपॉजिटरी को एक ही DbContextवस्तु का उपयोग करना चाहिए । ओपी के प्रस्तावित "स्वयं तात्कालिकता" के साथ, ऐसा करना असंभव हो जाता है।
फ्लेटर

1

मैंने Google Guice का उपयोग नहीं किया है, लेकिन मैंने पुरानी विरासत N-tier अनुप्रयोगों की ओर पलायन करने में बहुत समय लिया है। प्याज की परत की तरह IoC आर्किटेक्चर के लिए .Net, जो चीजों को डिकूप करने के लिए डिपेंडेंसी इंजेक्शन पर निर्भर है।

डिपेंडेंसी इंजेक्शन क्यों?

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

मुझे युग्मन के बारे में चिंता क्यों करनी चाहिए?

कपलिंग या तंग निर्भरता एक बहुत खतरनाक चीज हो सकती है। (विशेष रूप से संकलित भाषाओं में) इन मामलों में आपके पास एक पुस्तकालय, dll, आदि हो सकता है जो बहुत ही कम उपयोग किया जाता है जिसमें एक मुद्दा है जो प्रभावी रूप से पूरे आवेदन को ऑफ़लाइन लेता है। (आपका पूरा आवेदन मर जाता है क्योंकि एक महत्वहीन टुकड़ा एक मुद्दा है ... यह बुरा है ... वास्तव में बुरा है) अब जब आप चीजों को डिकूप करते हैं तो आप वास्तव में अपने आवेदन को सेटअप कर सकते हैं ताकि यह चल सके भले ही DLL या लाइब्रेरी पूरी तरह से गायब हो! यकीन है कि एक टुकड़ा है कि पुस्तकालय या DLL काम नहीं करेगा की जरूरत है, लेकिन आवेदन के बाकी खुश हो सकता है पर chugs।

मुझे उचित परीक्षण के लिए डिपेंडेंसी इंजेक्शन की आवश्यकता क्यों है

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

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

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

विचार यह है कि आप यह सुनिश्चित करना चाहते हैं कि पूरी कार्यक्षमता काम कर रही है, यदि आप नहीं चाहते कि कोड का सटीक टुकड़ा जो काम नहीं कर रहा है।

यह कर सकते हैं निर्भरता इंजेक्शन के बिना किया जा, लेकिन आम तौर पर अपनी परियोजना के रूप में यह अधिक से अधिक बोझिल जगह में निर्भरता इंजेक्शन के बिना ऐसा करने के लिए हो जाता है बढ़ता है। (हमेशा मान लें कि आपकी परियोजना आगे बढ़ेगी! बेहतर होगा कि उपयोगी कौशल का अभ्यास करना बेहतर हो, जैसे कि कोई प्रोजेक्ट तेजी से आगे बढ़ रहा हो और चीजों को पहले ही उतारने के बाद गंभीर रीफैक्टरिंग और रीइंजीनियरिंग की आवश्यकता हो।)


1
एक बड़े हिस्से का उपयोग करके परीक्षण लिखना लेकिन निर्भरता ग्राफ के सभी नहीं वास्तव में DI के लिए एक अच्छा तर्क है।
oberlies

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

0

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

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

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


0

मुझे लगता है कि यह एक बड़ी गलतफहमी है।

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

यह निर्माता:

BillingService(CreditCardProcessor processor, TransactionLog transactionLog)
{
    this.processor = processor;
    this.transactionLog = transactionLog;
}

पहले से ही निर्भरता इंजेक्शन का उपयोग करता है। आपने मूल रूप से सिर्फ यह कहा था कि DI का उपयोग करना आसान है।

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

यह निर्भरता इंजेक्शन फ्रेमवर्क करता है। लेकिन कंस्ट्रक्टर खुद जिसे आपने प्रस्तुत किया है वह पहले से ही डिपेंसेंसी इंजेक्शन सिद्धांत का कार्यान्वयन है । IoC कंटेनर और DI चौखटे इसी सिद्धांत को स्वचालित करने के लिए हैं, लेकिन हाथ से सब कुछ करने के लिए आपको रोकना कुछ भी नहीं है, यह पूरे बिंदु था।

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