कृपया मुझे IoC कंटेनरों पर बेचें


17

मैंने कोड में IoC कंटेनरों के उपयोग की कई सिफारिशें देखी हैं। प्रेरणा सरल है। निम्नलिखित निर्भरता इंजेक्शन कोड ले लो:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest(
        std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
    ) : d_(d)
    {
    }
};


TEST(UnitUnderTest, Example)
{
    std::auto_ptr<Dependency> dep(new MockDependency);
    UnitUnderTest uut(dep);
    //Test here
}

में:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest()
    {
        d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
    }
};


TEST(UnitUnderTest, Example)
{
    UnitUnderTest uut;
    //Test here
}

//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>

//Config for IOC container for testing
<Dependency>MockDependency</Dependency>

(उपरोक्त काल्पनिक C ++ का उदाहरण है)

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

तो .. क्या इस प्रकार के कंटेनरों का उपयोग करने के अन्य लाभ हैं या क्या मैं कंटेनर की सिफारिश करने वालों से असहमत हूं?


1
नमूना कोड एक आईओसी कार्यान्वयन के वास्तव में खराब उदाहरण की तरह दिखता है। मैं केवल C # से परिचित हूं लेकिन निश्चित रूप से C ++ में कंस्ट्रक्टर इंजेक्शन और प्रोग्रामेटिक कॉन्फ़िगरेशन का एक तरीका है?
rmac

जवाबों:


12

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

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

विभिन्न प्रकार के कंटेनर हैं, साथ ही साथ। उन सभी को कड़ाई से टाइप नहीं किया गया है, और उनमें से सभी को कॉन्फ़िगरेशन फ़ाइलों की आवश्यकता नहीं है।


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

... जारी ... जब कार्यक्रम का परीक्षण नहीं किया जा रहा है, तो डिफ़ॉल्ट ठोस निर्भरता प्रत्येक चरण पर त्वरित हो जाती है। अन्य प्रकार के कंटेनरों को लिखिए, क्या आपके पास कुछ उदाहरण हैं?
बिली ओनली

4
TBH मैं DI कार्यान्वयन के साथ अनुभव के टन नहीं है, लेकिन .NET पर MEF पर एक नज़र रखना, जो हो सकता है, लेकिन इसे कड़ाई से टाइप नहीं करना पड़ता है, कोई भी कॉन्फ़िगर फ़ाइल नहीं है, और इंटरफेस के ठोस कार्यान्वयन "पंजीकृत" हैं कक्षाओं में ही। BTW, जब आप कहते हैं: "निर्माणकर्ता उन्हें बनाने का ध्यान रखता है" - यदि आप यही कर रहे हैं (उर्फ "गरीब आदमी का निर्माता इंजेक्शन"), तो आपको कंटेनर की आवश्यकता नहीं है। एक कंटेनर का लाभ यह है कि कंटेनर उन सभी निर्भरता के बारे में जानकारी को केंद्रीकृत करता है।

+1 कि अंतिम टिप्पणी के लिए - अंतिम वाक्य में उत्तर है :)
बिली ओनली

1
महान जवाब जिसने मुझे पूरे बिंदु को जकड़ने में मदद की। बिंदु केवल बॉयलरप्लेट को सरल नहीं कर रहा है, लेकिन निर्भरता श्रृंखला के शीर्ष पर तत्वों को तल पर तत्वों के रूप में सिर्फ भोले होने की अनुमति देता है।
क्रिस्टोफर बर्मन

4

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

मेरा मानना ​​है कि Guice जावा IoC फ्रेमवर्क है जो आखिरकार कॉन्फ़िगरेशन सही मिला।


क्या C ++ के लिए कोई समान उदाहरण हैं?
बिली ओनेल

@ बिली, मैं सी ++ के साथ पर्याप्त रूप से परिचित नहीं हूं जो कहने में सक्षम हो।

0

बेन Scheirman द्वारा यह महान एसओ उत्तर C # में कुछ कोड उदाहरणों का विवरण देता है; IoC कंटेनर (DI) के कुछ फायदे:

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

1
मैं यह नहीं देखता कि उन चीजों में से कोई भी साधारण कंस्ट्रक्टर इंजेक्शन के साथ कैसे लागू नहीं किया जा सकता है।
बिली ओनेल

एक अच्छे डिजाइन के साथ, कंस्ट्रक्टर इंजेक्शन या कोई अन्य विधि आपके लिए पर्याप्त हो सकती है; इन IoC कंटेनरों के फायदे केवल विशिष्ट मामलों में हो सकते हैं। WPF प्रोजेक्ट में INotifyPropertyChanged के साथ दिया गया उदाहरण एक ऐसा उदाहरण था।
dodgy_coder
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.