नियंत्रण बनाम निर्भरता इंजेक्शन का उलटा


525

मार्टिन फाउलर द्वारा लिखे गए पत्र के अनुसार , नियंत्रण का व्युत्क्रम वह सिद्धांत है जहां किसी प्रोग्राम के नियंत्रण प्रवाह को उलटा किया जाता है: प्रोग्रामर के बजाय एक प्रोग्राम के प्रवाह को नियंत्रित करने के लिए, बाहरी स्रोत (फ्रेमवर्क, सर्विसेज, अन्य घटक) नियंत्रण लेते हैं। यह। यह ऐसा है जैसे हम किसी चीज को किसी और चीज में प्लग करते हैं। उन्होंने EJB 2.0 के बारे में एक उदाहरण का उल्लेख किया:

उदाहरण के लिए सत्र बीन इंटरफ़ेस ejbRemove, ejbPassivate (द्वितीयक भंडारण के लिए संग्रहीत), और ejbActivate (निष्क्रिय स्थिति से बहाल) को परिभाषित करता है। जब इन विधियों को बुलाया जाता है, तो आप नियंत्रित नहीं करते हैं, बस वे क्या करते हैं। कंटेनर हमें कॉल करता है, हम उसे कॉल नहीं करते हैं।

इससे फ्रेमवर्क और लाइब्रेरी के बीच अंतर होता है:

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

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

हालाँकि, इस पेपर में (पोकोकैपलस से, C / C ++ के लिए एक और IOC फ्रेमवर्क), यह बताता है कि IOC और DI के कारण, IOC कंटेनर और DI चौखटे J2EE से कहीं अधिक श्रेष्ठ हैं, क्योंकि J2EE के घटकों में ढाँचा कोड होता है। , इस प्रकार यह पुराने जावा / C ++ ऑब्जेक्ट (POJO / POCO) नहीं बना रहा है।

डिपेंडेंसी इंजेक्शन पैटर्न (आर्काइव लिंक) के अलावा कंट्रोल कंटेनरों का उलटा

पुराने घटक-आधारित विकास ढांचे के साथ समस्या क्या है, यह समझने के लिए अतिरिक्त रीडिंग, जो ऊपर दिए गए दूसरे पेपर की ओर ले जाता है: क्यों और कैसे नियंत्रण के उलटा (पुरालेख लिंक)

मेरा प्रश्न : वास्तव में IOC और DI क्या है? मैं उलझन में हूं। Pococapusel के आधार पर, IOC ऑब्जेक्ट्स या प्रोग्रामर और फ्रेमवर्क के बीच नियंत्रण के व्युत्क्रम की तुलना में कुछ अधिक महत्वपूर्ण है।


2
यहाँ इस विषय पर एक अच्छा राइटअप है, IoC बनाम DI (डिपेंडेंसी इंजेक्शन) बनाम SL (सर्विस लोकेटर): tinyurl.com/kk4be58 - url से निकालें: IoC बनाम DI (डिपेंडेंसी इंजेक्शन)? आईओसी सामान्य अवधारणा है जहां प्रवाह का नियंत्रण ग्राहक कोड से फ्रेमवर्क में उलटा होता है , जो "क्लाइंट के लिए कुछ करता है"। SL (सेवा लोकेटर) और DI (निर्भरता इंजेक्शन) IoC से दो डिज़ाइन पैटर्न हैं।
स्व.जाट

मेरे दो सेंट जोड़ने के लिए, यदि कोई इस बात में दिलचस्पी रखता है कि कॉफी शॉप थीम में निर्भरता इंजेक्शन कैसे सहायक हो सकता है, तो मैंने उस पर एक लेख लिखा है: digigene.com/design-patterns/d dependency
अली नेम


निर्भरता का उलटा: सार पर निर्भर करता है, न कि सहमति पर। नियंत्रण का उलटा: मुख्य बनाम अमूर्त, और मुख्य प्रणालियों का गोंद कैसे है। ये इस बारे में बात करने वाले कुछ अच्छे पोस्ट हैं: coderstower.com/2019/03/26/… coderstower.com/2019/04/02/… coderstower.com/2019/04/09/…
डैनियल एंड्रेस

इस गहरे के बारे में पढ़ें, यह सभी मार्टिनफॉवलर
दुश्मन

जवाबों:


644

आईओसी एक सामान्य शब्द है जिसका अर्थ है आवेदन को एक ढांचे में विधियों को कॉल करने के बजाय, फ्रेमवर्क एप्लिकेशन द्वारा प्रदान किए गए कार्यान्वयन को कॉल करता है।

DI आईओसी का एक रूप है, जहां कार्यान्वयन को ऑब्जेक्ट्स में कंस्ट्रक्टर / सेटर / सर्विस लुक्स के माध्यम से पास किया जाता है, जिसे सही ढंग से व्यवहार करने के लिए ऑब्जेक्ट 'पर निर्भर करेगा'।

DI का उपयोग किए बिना IoC , उदाहरण के लिए टेम्प्लेट पैटर्न होगा क्योंकि कार्यान्वयन केवल उप-वर्गीकरण के माध्यम से बदला जा सकता है।

DI चौखटे डीआई का उपयोग करने के लिए डिज़ाइन किए गए हैं और यह इंटरफेस (या जावा में एनोटेशन) को परिभाषित कर सकते हैं ताकि कार्यान्वयन में आसानी हो सके।

IoC कंटेनर DI चौखटे हैं जो प्रोग्रामिंग भाषा के बाहर काम कर सकते हैं। कुछ में आप कॉन्फ़िगर कर सकते हैं कि मेटाडेटा फ़ाइलों (जैसे XML) में उपयोग करने के लिए कौन से कार्यान्वयन कम आक्रामक हैं। कुछ के साथ आप आईओसी कर सकते हैं जो सामान्य रूप से असंभव होगा जैसे पॉइंटकट पर कार्यान्वयन लागू करना ।

मार्टिन फाउलर का यह लेख भी देखें ।


2
जवाब के लिए धन्यवाद। लेकिन दूसरे पेपर से पता चलता है कि IOC के साथ, IOC कंटेनर EJB से कहीं अधिक श्रेष्ठ हैं, जबकि मार्टिन Fowler सुझाव देते हैं कि EJB IOC का एक विशिष्ट उदाहरण है।
अमुमु

5
EJB प्रबंधन वास्तव में IoC का एक विशिष्ट उदाहरण है। आप इसे इस तथ्य से देख सकते हैं कि ईजेबी का जीवनचक्र कंटेनर द्वारा प्रबंधित किया जाता है, प्रोग्रामर द्वारा नहीं। प्रोग्रामर ईजेबी इंस्टेंस को बनाता या नष्ट नहीं करता है क्योंकि नियंत्रण सर्वर पर दिया जाता है । यह IoC की अवधारणा है: जब आपका कोड कहा जाता है, तो बाहरी कोड नियंत्रित करता है, जो आमतौर पर इसका सबसे उलटा होता है।
ब्रांडीजी

2
आईओसी एक सामान्य शब्द है जिसका अर्थ है आवेदन को एक ढांचे में तरीकों को कॉल करने के बजाय, फ्रेमवर्क एप्लिकेशन द्वारा प्रदान किए गए कार्यान्वयन को कॉल करता है। क्या आप इसके बारे में अधिक बता सकते हैं?
इमाद अल्ज़ानी

21
Aka हॉलीवुड सिद्धांत , 'हमें फोन मत करो, हम तुम्हें फोन करेंगे'। आवेदन के बजाय ढांचे तक के आह्वान को छोड़ देता है।
गैरेट हॉल

@ImadAlazani, आप बेहतर तरीके से उस लेख के माध्यम से पढ़ेंगे, जो गैरेट ने संलग्न किया है, जो कि एप्लीकेशन कोड से फ्रेमवर्क पर नियंत्रण प्राप्त करने के बारे में एक विस्तृत चर्चा है।
मेंगट

210

संक्षेप में, आईओसी एक बहुत व्यापक शब्द है जिसमें शामिल है, लेकिन डीआई तक सीमित नहीं है

शब्द इनवर्जन ऑफ कंट्रोल (IoC) का मूल रूप से किसी भी प्रकार की प्रोग्रामिंग शैली का मतलब था जहां एक समग्र रूपरेखा या रन-टाइम ने प्रोग्राम प्रवाह को नियंत्रित किया

DI का नाम होने से पहले, लोगों ने ऐसे फ्रेमवर्क का उल्लेख करना शुरू कर दिया था जो डिपेंडेंसी को कंट्रोल कंटेनरों के व्युत्क्रम के रूप में प्रबंधित करते हैं, और जल्द ही, IoC का अर्थ धीरे-धीरे उस विशेष अर्थ की ओर बढ़ गया: डिपेंडेंसी पर नियंत्रण का उलटा।

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

डिपेंडेंसी इंजेक्शन (DI) का अर्थ है कि यह वस्तु के हस्तक्षेप के बिना किया जाता है, आमतौर पर एक फ्रेमवर्क घटक द्वारा जो कंस्ट्रक्टर मापदंडों और सेट गुणों से गुजरता है।


1
IoC की तरह लगता है कि डिप्रेशन उलटा सिद्धांत के लिए सिर्फ एक और शब्द है, नहीं?
टॉड वंस

@ToddVance - हां, मुझे लगता है कि IoC और DIP एक ही चीज हैं। डीआईपी और डीआई एक ही चीज नहीं हैं। Io बिना DI के किया जा सकता है, लेकिन DI Io के बिना नहीं किया जा सकता है।
एलजय

2
@ToddVance - नहीं, DIP और IoC समानार्थी नहीं हैं और संबंधित नहीं हैं।
टीस्मिथ

3
हा, यही कारण है कि मैं इस धागे पर यहाँ हूँ ... "नियंत्रण बनाम निर्भरता इंजेक्शन का"
टॉड वैन्स

50

यहाँ छवि विवरण दर्ज करें
स्रोत

आईओसी ( मैं n संस्करण सी ontrol): - यह एक सामान्य शब्द और कई तरीके (घटनाओं, प्रतिनिधियों आदि) में लागू किया है।

DI ( D एपेंडेंसी I njection): - DI एक प्रकार का IoC है और इसे कंस्ट्रक्टर इंजेक्शन, सेटर इंजेक्शन या इंटरफ़ेस इंजेक्शन द्वारा कार्यान्वित किया जाता है ।

लेकिन, स्प्रिंग केवल निम्नलिखित दो प्रकारों का समर्थन करता है:

  • सेटर इंजेक्शन
    • सेटर-आधारित डि को उनके बीन को तुरंत भरने के लिए नो-लॉजिक कंस्ट्रक्टर या नो-लॉजिक स्टैटिक फैक्ट्री मेथड को लागू करने के बाद उपयोगकर्ता के सेम पर सेटर विधियों को कॉल करके महसूस किया जाता है।
  • कंस्ट्रक्टर इंजेक्शन
    • कंस्ट्रक्टर-आधारित डीआई को एक निर्माता को कई तर्कों के साथ आमंत्रित करके महसूस किया जाता है, प्रत्येक एक सहयोगी का प्रतिनिधित्व करते हैं। इसका उपयोग करते हुए हम यह पुष्टि कर सकते हैं कि इंजेक्ट किए गए बीन्स शून्य नहीं हैं और तेजी से विफल हो जाते हैं (संकलन समय पर विफल होते हैं और रन-टाइम पर नहीं), इसलिए आवेदन शुरू करते समय हम खुद को प्राप्त करते हैं NullPointerException: bean does not exist। कंस्ट्रक्टर इंजेक्शन निर्भरता को इंजेक्ट करने के लिए सबसे अच्छा अभ्यास है।

1
यह सही नहीं है कि वसंत संपत्ति के इंजेक्शन का समर्थन नहीं करता है। ऐसा होता है। और यह एक बुरा अभ्यास है, मैं सहमत हूं।
kekko12

स्प्रिंग @Autowired एनोटेशन मेरी राय में संपत्ति इंजेक्शन का एक तरीका है
सजीथ

49

DI, IoC का एक उपसमूह है

  • IoC का अर्थ है कि ऑब्जेक्ट अन्य ऑब्जेक्ट नहीं बनाते हैं, जिस पर वे अपना काम करने के लिए भरोसा करते हैं। इसके बजाय, उन्हें वे वस्तुएँ मिलती हैं जिनकी उन्हें बाहर की सेवा (उदाहरण के लिए, xml फ़ाइल या एकल ऐप सेवा) से आवश्यकता होती है। आईओसी के 2 कार्यान्वयन, मैं उपयोग करता हूं, डीआई और सर्विसलोकेटर हैं।
  • DI का अर्थ है ठोस वस्तुओं का उपयोग किए बिना, लेकिन सार (इंटरफेस) के बिना निर्भर वस्तु प्राप्त करने का IoC सिद्धांत। यह सभी घटकों की श्रृंखला को परीक्षण योग्य बनाता है, क्योंकि उच्च स्तर का घटक निचले स्तर के घटक पर निर्भर नहीं करता है, केवल इंटरफ़ेस से। मोक्स इन इंटरफेस को लागू करते हैं।

आईओसी हासिल करने के लिए यहां कुछ अन्य तकनीकें दी गई हैं


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

19

चूँकि सभी उत्तर सिद्धांत पर जोर देते हैं, मैं उदाहरण के साथ पहले दृष्टिकोण का प्रदर्शन करना चाहूंगा:

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

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

उपरोक्त कार्यान्वयन गलत नहीं है, लेकिन कुछ मुद्दे हैं:
-) मान लीजिए कि विकास के माहौल में, आप इसे प्राप्त करने के लिए, एसएमएस गेटवे का उपयोग करने के बजाय एक पाठ फ़ाइल पर भेजे गए एसएमएस को सहेजना चाहते हैं; हम (SMSService) के ठोस कार्यान्वयन को एक और कार्यान्वयन के साथ समाप्त करेंगे, हम लचीलापन खो रहे हैं और इस मामले में कोड को फिर से लिखने के लिए मजबूर हैं।
-) हम कक्षाओं की मिश्रित जिम्मेदारियों को समाप्त करेंगे, हमारे (UIHandler) को (SMSService) के ठोस कार्यान्वयन के बारे में कभी नहीं पता होना चाहिए, यह "इंटरफेस" का उपयोग करके कक्षाओं के बाहर किया जाना चाहिए। जब यह लागू हो जाता है, तो यह हमें एक और नकली सेवा के साथ प्रयोग की जाने वाली प्रणाली (SMSService) को स्वैप करके सिस्टम के व्यवहार को बदलने की क्षमता देगा जो समान इंटरफ़ेस को लागू करता है, यह सेवा मोबाइल फोन पर भेजने के बजाय एसएमएस को एक पाठ फ़ाइल में बचाएगा।

उपरोक्त मुद्दों को ठीक करने के लिए हम उन इंटरफेस का उपयोग करते हैं जिन्हें हमारे (SMSService) और नए (MockSMSService) द्वारा कार्यान्वित किया जाएगा, मूल रूप से नया इंटरफ़ेस (ISMSService) दोनों सेवाओं के समान व्यवहार को नीचे दिए गए कोड के रूप में उजागर करेगा:

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

तब हम (ISMSService) इंटरफ़ेस को लागू करने के लिए अपना (SMSService) कार्यान्वयन बदल देंगे:

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

अब हम एक ही इंटरफ़ेस का उपयोग करके पूरी तरह से अलग कार्यान्वयन के साथ नई मॉक अप सेवा (MockSMSService) बनाने में सक्षम होंगे:

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

इस बिंदु पर, हम (UIHandler) कोड को सेवा के ठोस कार्यान्वयन (MockSMSService) का उपयोग आसानी से नीचे के रूप में कर सकते हैं:

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

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

इसे प्राप्त करने के लिए, हमें इसके माध्यम से निर्भरता को पारित करने के लिए अपने (UIHandler) वर्ग निर्माता में बदलाव लागू करने की आवश्यकता है, ऐसा करने से, कोड (UIHandler) का उपयोग करने वाले निर्धारित कर सकते हैं कि कौन सा (ISMSService) का उपयोग करने के लिए ठोस कार्यान्वयन है:

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

अब UI फॉर्म जो क्लास (UIHandler) के साथ बात करेगा, उपभोग करने के लिए इंटरफ़ेस (ISMSService) के कार्यान्वयन को पारित करने के लिए जिम्मेदार है। इसका मतलब है कि हमने नियंत्रण को उल्टा कर दिया है, (UIHandler) अब यह तय करने के लिए ज़िम्मेदार नहीं है कि कौन से कार्यान्वयन का उपयोग करना है, कॉलिंग कोड करता है। हमने नियंत्रण के व्युत्क्रम को लागू किया है जो DI एक प्रकार का है।

यूआई फॉर्म कोड नीचे दिया जाएगा:

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}

महान व्याख्या
ZiviMagic 13

19

आईओसी (नियंत्रण का उलटा) : वस्तु का एक उदाहरण प्राप्त करने के लिए कंटेनर को नियंत्रण देना इसे नियंत्रण का व्युत्क्रम कहा जाता है, इसका मतलब है कि आप नए ऑपरेटर का उपयोग करके एक वस्तु का निर्माण कर रहे हैं, कंटेनर को आपके लिए ऐसा करने दें।

DI (डिपेंडेंसी इंजेक्शन) : किसी ऑब्जेक्ट में गुणों को इंजेक्ट करने के तरीके को डिपेंडेंसी इंजेक्शन कहा जाता है ।

हमारे पास डिपेंडेंसी इंजेक्शन के तीन प्रकार हैं :

  1. कंस्ट्रक्टर इंजेक्शन
  2. सेटर / गेट्टर इंजेक्शन
  3. इंटरफ़ेस इंजेक्शन

स्प्रिंग केवल कंस्ट्रक्टर इंजेक्शन और सेटर / गेट्टर इंजेक्शन का समर्थन करता है ।


5

लेकिन वसंत प्रलेखन का कहना है कि वे समान हैं।

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

पहली पंक्ति में " IoC को निर्भरता इंजेक्शन (DI) " के रूप में भी जाना जाता है


1
मुझे लगता है कि वे जो संबोधित करने की कोशिश कर रहे थे वह यह है कि DI आईओसी डिजाइन पैटर्न का एक बहुत व्यापक रूप से उपयोग किया जाने वाला स्वाद है कि इसे लगभग आसानी से IoC उर्फ ​​DI कहा जा सकता है - जब तक कि दस्तावेज़ में कोई स्पष्ट संदर्भ न हो जो अन्यथा सुझाव देता है।
ha9u63ar

5
"IoC को निर्भरता इंजेक्शन (DI) के रूप में भी जाना जाता है ..." घोडे के पंख!
माइक 31

5

IoC - नियंत्रण का व्युत्क्रम सामान्य शब्द है, भाषा से स्वतंत्र है, यह वास्तव में वस्तुओं का निर्माण नहीं करता है, बल्कि यह वर्णन करता है कि फैशन वस्तु किसमें बनाई जा रही है।

DI - निर्भरता इंजेक्शन ठोस शब्द है, जिसमें हम विभिन्न इंजेक्शन तकनीकों का उपयोग करके रन टाइम में ऑब्जेक्ट की निर्भरता प्रदान करते हैं। सेटर इंजेक्शन, निर्माता इंजेक्शन या इंटरफ़ेस इंजेक्शन द्वारा।


4

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

नियंत्रण के व्युत्क्रम को लागू करने के लिए कई बुनियादी तकनीकें हैं। य़े हैं:

  • फैक्टरी पैटर्न का उपयोग करना
  • एक सेवा लोकेटर पैटर्न का उपयोग करना
  • नीचे दिए गए किसी भी प्रकार के निर्भरता इंजेक्शन का उपयोग करना:

    1)। एक कंस्ट्रक्टर इंजेक्शन
    2)। एक सेटर इंजेक्शन
    3)। एक इंटरफ़ेस इंजेक्शन

4

DI और IOC दो डिज़ाइन पैटर्न हैं जो मुख्य रूप से घटकों के बीच ढीली युग्मन प्रदान करने पर ध्यान केंद्रित कर रहे हैं , या बस एक तरह से जिसमें हम ऑब्जेक्ट के बीच पारंपरिक निर्भरता संबंधों को कम कर देते हैं ताकि ऑब्जेक्ट एक दूसरे से तंग न हों।

निम्नलिखित उदाहरणों के साथ, मैं इन दोनों अवधारणाओं को समझाने की कोशिश कर रहा हूं।

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

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();
}

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

IOC वह सिद्धांत है जहां किसी प्रोग्राम के कंट्रोल फ्लो को उलटा किया जाता है: प्रोग्रामर के बजाय प्रोग्राम के फ्लो को कंट्रोल करने के लिए प्रोग्रामर को ओवरहेड को कम करके प्रोग्राम को फ्लो को कंट्रोल करता है। और प्रोग्राम द्वारा डिपेंडेंसी को इंजेक्ट करने के लिए जिस प्रोसेस का इस्तेमाल किया जाता है उसे टर्मिनेट किया जाता है। डि

दो अवधारणाएँ एक साथ काम करते हुए हमें अधिक लचीला, पुन: प्रयोज्य, और कूटबद्ध कोड लिखने का एक तरीका प्रदान करती हैं, जो उन्हें ऑब्जेक्ट-ओरिएंटेड समाधानों को डिजाइन करने में महत्वपूर्ण अवधारणाओं के रूप में बनाते हैं।

पढ़ने की भी सलाह देते हैं।

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

आप यहाँ मेरे एक समान उत्तर को भी देख सकते हैं

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


3

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

यह एक डिजाइन सिद्धांत है जिसमें सामान्य लिखित पुस्तकालय या पुन: प्रयोज्य कोड से नियंत्रण का प्रवाह "प्राप्त" होता है।

इसे बेहतर ढंग से समझने के लिए, हम देखते हैं कि कोडिंग के पहले के दिनों में हम कैसे कोड करते थे। प्रक्रियात्मक / पारंपरिक भाषाओं में, व्यावसायिक तर्क आमतौर पर एप्लिकेशन के प्रवाह को नियंत्रित करता है और सामान्य या पुन: प्रयोज्य कोड / फ़ंक्शन को "कॉल" करता है। उदाहरण के लिए, एक साधारण कंसोल एप्लिकेशन में, मेरे प्रोग्राम के निर्देशों द्वारा मेरा नियंत्रण नियंत्रित किया जाता है, जिसमें कुछ सामान्य पुन: प्रयोज्य कार्यों के लिए कॉल शामिल हो सकते हैं।

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

आईओआरसी के साथ कंट्रास्ट में, फ्रेमवर्क पुन: प्रयोज्य कोड है जो व्यापार तर्क को "कॉल" करता है।

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

हालाँकि, फ्रेमवर्क कोड को मेरे व्यावसायिक तर्क के बारे में पता नहीं है, फिर भी यह पता चलेगा कि मेरे कोड को कैसे कॉल किया जाए। यह ईवेंट्स / डेलीगेट्स, कॉलबैक आदि का उपयोग करके हासिल किया जाता है। यहाँ प्रवाह का नियंत्रण "उलटा" है।

इसलिए, सांख्यिकीय रूप से बाध्य वस्तुओं पर नियंत्रण के प्रवाह के आधार पर, प्रवाह समग्र वस्तु ग्राफ और विभिन्न वस्तुओं के बीच संबंधों पर निर्भर करता है।

डिपेंडेंसी इंजेक्शन एक डिज़ाइन पैटर्न है जो वस्तुओं की निर्भरता को हल करने के लिए IoC सिद्धांत को लागू करता है।

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

एक साधारण सादृश्य एक क्लास कार होगा। एक कार इंजन, टायर और अन्य जैसे अन्य वर्गों पर निर्भर हो सकती है।

डिपेंडेंसी इंजेक्शन बताता है कि डिपेंडेंट क्लासेस (क्लास कार) के बजाय अपनी निर्भरता (क्लास इंजन और क्लास टायर) बनाने के लिए, क्लास को डिपेंडेंसी के ठोस उदाहरण के साथ इंजेक्ट किया जाना चाहिए।

अधिक व्यावहारिक उदाहरण से समझें। विचार करें कि आप अपना खुद का TextEditor लिख रहे हैं। अन्य बातों के अलावा, आप एक वर्तनी जाँचक हो सकते हैं जो उपयोगकर्ता को अपने पाठ में टाइपोस की जांच करने की सुविधा प्रदान करता है। इस तरह के एक कोड का एक सरल कार्यान्वयन हो सकता है:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

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

सब कुछ एक महान दिन तक काम करने लगता है जब एक उपयोगकर्ता संपादक में फ्रेंच लिखना शुरू करता है।

अधिक भाषाओं के लिए सहायता प्रदान करने के लिए, हमें और अधिक SpellCheckers रखने की आवश्यकता है। संभवतः फ्रेंच, जर्मन, स्पेनिश आदि।

यहां, हमने "इंग्लिश" स्पेलचैकर के साथ हमारे TextEditor वर्ग के साथ कसकर युग्मित कोड बनाया है, जिसका अर्थ है कि हमारा TextEditor वर्ग EnglishSpellChecker पर निर्भर है या अन्य अंग्रेजी में SpellCheker TextEditor के लिए निर्भरता है। हमें इस निर्भरता को दूर करने की आवश्यकता है। इसके अलावा, हमारे पाठ संपादक को रन टाइम में डेवलपर के विवेक के आधार पर किसी भी वर्तनी परीक्षक के ठोस संदर्भ को रखने का एक तरीका चाहिए।

इसलिए, जैसा कि हमने DI के परिचय में देखा, यह सुझाव देता है कि वर्ग को अपनी निर्भरता के साथ इंजेक्ट किया जाना चाहिए। तो, यह कॉलिंग कोड की जिम्मेदारी होनी चाहिए कि वह सभी निर्भरता को इंजेक्टेड क्लास / कोड को बताए। इसलिए हम अपने कोड का पुनर्गठन कर सकते हैं

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

हमारे उदाहरण में, TextEditor वर्ग को ISpellChecker प्रकार का ठोस उदाहरण प्राप्त करना चाहिए।

अब, निर्भरता को कंस्ट्रक्टर, एक सार्वजनिक संपत्ति या एक विधि में इंजेक्ट किया जा सकता है।

कंस्ट्रक्टर डि का उपयोग करके हमारी कक्षा को बदलने की कोशिश करें। परिवर्तित TextEditor वर्ग कुछ इस तरह दिखाई देगा:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

ताकि टेक्स्ट एडिटर बनाते समय कॉलिंग कोड, टेक्स्ट एडिटर के उदाहरण के लिए उपयुक्त SpellChecker प्रकार को इंजेक्ट कर सके।

पूरा लेख आप यहां पढ़ सकते हैं


3

IOC (नियंत्रण का व्युत्क्रम): वस्तु का उदाहरण प्राप्त करने के लिए कंटेनर पर नियंत्रण देना, नियंत्रण का व्युत्क्रम कहलाता है। इसका मतलब है कि आप के बजाय नए ऑपरेटर का उपयोग करके ऑब्जेक्ट बना रहे हैं , कंटेनर को आपके लिए ऐसा करने दें।

DI (डिपेंडेंसी इंजेक्शन): XML से किसी ऑब्जेक्ट (POJO CLASS) में आवश्यक पैरामीटर (गुण) पास करना डिपेंडेंसी इंजेक्शन कहलाता है।


2

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

आईओसी कंटेनर द्वारा किए गए मुख्य कार्य हैं: आवेदन वर्ग को तत्काल करना। ऑब्जेक्ट को कॉन्फ़िगर करने के लिए। वस्तुओं के बीच निर्भरता को इकट्ठा करना।

डि सेटर इंजेक्शन या कंस्ट्रक्टर इंजेक्शन का उपयोग करके रन टाइम में किसी वस्तु की निर्भरता प्रदान करने की प्रक्रिया है।


2

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

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

निर्भरता इंजेक्शन: - DI आईओसी का एक उपप्रकार है और कंस्ट्रक्टर इंजेक्शन, सेटर इंजेक्शन या विधि इंजेक्शन द्वारा कार्यान्वित किया जाता है।

निम्नलिखित लेख बहुत बड़े करीने से इसका वर्णन करता है।

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO


1

मुझे लगता है कि ऑब्जेक्ट ओरिएंटेड खरपतवारों को प्राप्त किए बिना विचार को स्पष्ट रूप से प्रदर्शित किया जा सकता है, जो विचार को कुंद कर रहे हैं।

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

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


0

आइए SOLID के D से शुरू करते हैं और स्कॉट बाजरा की पुस्तक "प्रोफेशनल ASP.NET डिजाइन पैटर्न" से DI और IoC को देखते हैं:

निर्भरता उलटा सिद्धांत (DIP)

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

निर्भरता इंजेक्शन (DI) और नियंत्रण का उलटा (IoC)

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

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

बाजरा, सी (2010)। पेशेवर ASP.NET डिजाइन पैटर्न। विली प्रकाशन। 7-8।


0

// ICO, DI, 10 साल पहले, यह तरीका था:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

अब स्प्रिंग 3,4 के साथ या नीचे की तरह नवीनतम

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

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


0

मुझे Dzone.com पर सबसे अच्छा उदाहरण मिला जो IOC और DI के बीच वास्तविक अंतर को समझने में वास्तव में सहायक है

"IoC तब होता है जब आपके पास कोई और आपके लिए ऑब्जेक्ट बनाता है।" इसलिए आपके कोड में "नया" कीवर्ड (उदाहरण के लिए, MyCode c = new MyCode ()) लिखने के बजाय ऑब्जेक्ट किसी और द्वारा बनाया गया है। इस 'किसी और' को आम तौर पर एक आईओसी कंटेनर के रूप में जाना जाता है। इसका मतलब है कि हम वस्तु का उदाहरण प्राप्त करने के लिए कंटेनर को rrsponsibility (नियंत्रण) सौंपते हैं, इसे कंट्रोल ऑफ कंट्रोल कहा जाता है, इसका मतलब है कि आप नए ऑपरेटर का उपयोग करके ऑब्जेक्ट बना रहे हैं, कंटेनर को आपके लिए ऐसा करने दें।

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

पूरा लेख IOC पढ़ें और पूरा लेख DI पढ़ें


0

1) DI बाल है-> obj माता-पिता-obj पर निर्भर करता है। क्रिया निर्भर करता है महत्वपूर्ण है। 2) IOC बाल है -> एक मंच के नीचे obj प्रदर्शन। जहाँ प्लेटफॉर्म स्कूल, कॉलेज, डांस क्लास हो सकता है। यहां प्रदर्शन किसी भी प्लेटफ़ॉर्म प्रदाता के तहत अलग-अलग निहितार्थ के साथ एक गतिविधि है।

व्यावहारिक उदाहरण: `

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB


0

इस प्रश्न के लिए, मैं कहता हूं कि विकी ने पहले से ही विस्तृत और आसान-समझ स्पष्टीकरण प्रदान किया है। मैं यहां सबसे महत्वपूर्ण उद्धरण दूंगा।

आईओसी का कार्यान्वयन

ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में, नियंत्रण के व्युत्क्रम को लागू करने के लिए कई बुनियादी तकनीकें हैं। य़े हैं:

  1. एक सेवा लोकेटर पैटर्न का उपयोग करना निर्भरता इंजेक्शन का उपयोग करना, उदाहरण के लिए कंस्ट्रक्टर इंजेक्शन पैरामीटर इंजेक्शन सेटर इंजेक्शन इंटरफ़ेस इंजेक्शन;
  2. एक प्रासंगिक खोज का उपयोग करना;
  3. टेम्पलेट विधि डिजाइन पैटर्न का उपयोग करना;
  4. रणनीति डिजाइन पैटर्न का उपयोग करना

निर्भरता इंजेक्शन के लिए के रूप में

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


0

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

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

इस लिहाज से DI , Io C के समान नहीं है , क्योंकि यह नियंत्रण-प्रवाह के बारे में नहीं है, हालांकि यह एक प्रकार का Io * है , अर्थात वस्तु-निर्माण के स्वामित्व का उलटा।

डीआई और आईओसी को समझाने के मेरे तरीके में क्या गलत है?

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