15

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

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

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

धन्यवाद!

आर

पी.एस. मैंने एकता को टैग किया क्योंकि यह मेरी वर्तमान व्यक्तिगत वरीयता है (मैं सिर्फ एंटरिब लूव)।

उत्तर

18

आप IContainer को Resolve और Register कहकर कंटेनर से एक अमूर्तता बनाने का प्रयास कर सकते हैं। मैंने दो बार ऐसा किया। फिर आप आगे बढ़ेंगे और कंटेनर लागू करेंगे: आईकॉन्टेनर और आपके अमूर्तता के साथ एक वास्तविक आईओसी कंटेनर को समाहित करें। मैंने एकता और कैसल विंडसर के साथ कोशिश की।

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

कोड overcomplicated लग रहा है, जैसे

//I did this mess with Service Locator 
var t = ContainerService.Instance.Resolve<IMyType>(); 
//others could go further with same Service Locator 
var t = IoCFactory.Instance.CurrentContainer.Resolve<IMyType>(); 

//better way, use --> IoC and DI <-- 
//when a program starts, or a new instance of the context created 
var t = Container.Resolve<IMyType>() //this lives at the bottom of the stack 
//and then you just pass IMyType to the constructor of other types  
//you don't need to call Resolve again in the logical cycle 

this post देखें Ayende द्वारा।

हां, उन्होंने नियंत्रण कंटेनर के उलटा सार को समझाया। मुझे लगता है कि अगर आपको ऐसा करने की ज़रूरत है, तो यह स्पष्ट है कि आपको वास्तव में आईओसी के बारे में क्या पता नहीं है।

+0

अच्छा बिंदु, सारणी IoC अतिदेय की तरह लगता है – pkmiec

+0

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

+0

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

3

Common Service Locator लाइब्रेरी देखें।

+6

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

+3

सीएसएल के डिजाइनरों में से एक के रूप में, मैं दृढ़ता से उपर्युक्त टिप्पणी का समर्थन करता हूं। सीएसएल लाइब्रेरी लेखकों के लिए है जो एक कंटेनर चाहते हैं, लेकिन ऐप पर लाइब्रेरी की कंटेनर की पसंद को मजबूर नहीं करना चाहते हैं। –

18

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

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

+5

कन्स्ट्रक्टर इंजेक्शन को प्राथमिकता देने के लिए बिल्कुल सही। – FMM

4

जैसा कि कुछ अन्य लोगों ने उल्लेख किया है, कन्स्ट्रक्टर इंजेक्शन पसंद करते हैं। इससे आपकी कई समस्याएं हल हो जाएंगी।

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

public class Foo 
{ 
    private MyIoCContainer _container; 

    public Foo(MyIoCContainer container) 
    { 
     this._container = container; 
    } 


    public void DoSomething() 
    { 
     // have to do this at runtime for whatever reason 
     var myObj = this._container.Resolve<ISomeType>(); 

     myObj.DoSomething(); 
     myObj.DoSomethingElse(); 
    } 
} 
इस के साथ

:

public class Foo 
{ 
    private IObjFactory _provider; 

    public Foo(IObjFactory _provider) 
    { 
     this._provider = provider; 
    } 


    public void DoSomething() 
    { 
     var myObj = _provider.GetObj(); 

     myObj.DoSomething(); 
     myObj.DoSomethingElse(); 
    } 
} 

public interface IObjFactory 
{ 
    ISomeType GetObj(); 
} 

अब, आप एक IObjFactory कि गतिशील, क्रम ऑब्जेक्ट ISomeType लागू निर्माण की प्रकृति को संपुटित सकते हैं। यदि आप कंटेनर/सेवा लोकेटर से कई अलग-अलग प्रकार के ऑब्जेक्ट का निर्माण कर रहे हैं, तो आपके पास कम से कम *Factory इंटरफेस होना चाहिए (Interface Segregation Principle के अनुसार)।

9

एक डी कंटेनर को केवल Composition Root से संदर्भित किया जाना चाहिए। अन्य सभी मॉड्यूल में कंटेनर का कोई संदर्भ नहीं होना चाहिए।

मार्क सीनैन (Dependency Injection in .NET के लेखक)

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

कन्स्ट्रक्टर इंजेक्शन आमतौर पर जाने का सही तरीका है, जैसा कि अन्य ने उल्लेख किया है। यदि आप फ्लाई पर ऑब्जेक्ट्स बनाने की ज़रूरत है तो आप फ़ैक्टरी इंटरफेस या Func<T> प्रतिनिधियों को इंजेक्ट कर सकते हैं।

मैं जब भी संभव हो एक्सएमएल कॉन्फ़िगरेशन से बचने का सुझाव देता हूं।

संबंधित मुद्दे