24

मैं एक पालतू परियोजना के लिए महल विंडसर का उपयोग कर रहा हूं जिस पर मैं काम कर रहा हूं। मुझे नोटिस करना शुरू हो रहा है कि मुझे नई ऑब्जेक्ट्स बनाने के लिए अपने कोड में विभिन्न स्थानों पर आईओसी कंटेनर को कॉल करने की आवश्यकता है। कंटेनर पर यह निर्भरता मेरे कोड को बनाए रखने के लिए कठिन बनाता है।आईओसी, आप कंटेनर कहां डालते हैं?

दो समाधान मैं इस समस्या

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

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

दोनों समाधान काम के प्रकार हैं लेकिन दोनों में उनकी कमी है। इसलिए मैं उत्सुक हूं कि अन्य लोगों को एक ही समस्या है और बेहतर समाधान मिल गए हैं।


संपादित समस्या वस्तु एक है कि वस्तु बी पर निर्भर करता है यहाँ मैं आम तौर पर सिर्फ निर्माता इंजेक्शन का उपयोग करें और सब कुछ काम करता है के लिए नहीं है। कभी-कभी मेरे पास टाइप ए की ऑब्जेक्ट होती है जिसे अपने जीवनकाल के दौरान बी के अन्य ऑब्जेक्ट्स की एक चर संख्या बनाने की आवश्यकता होती है। मुझे यकीन नहीं है कि यह कैसे करें।

@ ब्लेयर कॉनराड: रखरखाव के मुद्दे अब तक गंभीर नहीं हैं। मेरे पास कुछ वर्ग कंटेनर ऑब्जेक्ट कॉलिंग कंटेनर पर निर्भर थे। <> को हटाएं। और मैं अपने कोड को आधारभूत संरचना के आधार पर नहीं चाहता हूं। मैं अभी भी चीजों की कोशिश कर रहा हूं इसलिए मैंने देखा कि इस परियोजना के लिए निंजा से महल में स्विच करते समय मुझे बहुत सारे कोड बदलना पड़ा।

@flowers: हम्म। मुझे आपकी मुट्ठी समाधान पसंद है। यह उन चीजों को जोड़ती है जो मैंने कोशिश की दोनों समाधानों से काम करते हैं। मुझे लगता है कि मैं अभी भी वस्तुओं में बहुत ज्यादा सोच रहा था और इंटरफेस/जिम्मेदारियों में पर्याप्त नहीं था। मैंने उद्देश्य निर्मित कारखानों का प्रयास किया लेकिन मैं उन्हें वस्तुओं को बनाने के लिए दृश्यों के पीछे कंटेनर का उपयोग करना चाहता हूं और मुझे पता नहीं चला कि मैं कंटेनर को स्वच्छ तरीके से कैसे कर सकता हूं।

+0

मैं उत्सुक हूं, और उत्तर हमें जवाब देने में मदद कर सकते हैं। आपके पास किस प्रकार के रखरखाव के मुद्दे हैं? –

उत्तर

3

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

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

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

2

जबकि मैं "उद्देश्य निर्मित कारखानों" के स्पष्टीकरण की सराहना करता हूं और यहां तक ​​कि उन्हें स्वयं भी उपयोग करता हूं, यह मेरे स्वयं के डिज़ाइनों में कोड गंध की तरह लगता है क्योंकि सार्वजनिक इंटरफ़ेस (छोटा "i") एक नए कारखाने के साथ बदलता रहता है और/या प्रत्येक कार्यान्वयन के लिए एक नई GetX विधि। जेरेमी मिलर की It's time for IoC Container Detente पढ़ने के बाद, मैं जेनरिक संदेह है और कंटेनर में ही इंजेक्शन लगाने के जाने का रास्ता है।

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

IServiceLocator container = ContainerFactory.GetContainer(); 
while(keepLooping) 
{ 
    IExample example = container.GetInstance<IExample>(); 
    keepLooping = example.DoWork(); 
} 

आपका कंटेनर फैक्ट्री हमेशा एक ही इरादा वापस कर सकता है, आप जो भी आईओसी फ्रेमवर्क स्वैप कर सकते हैं।

11

कृपया, कभी भी IoC.Container.Resolve या ContainerFactory.GetContainer जैसे स्थिर वर्गों का उपयोग न करें!

यह कोड को अधिक जटिल, बनाए रखने, पुन: उपयोग करने और पढ़ने के लिए परीक्षण करने में कठोर बनाता है।

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

अपने घटक वास्तव में (यानी, को हल करने के अपवाद हैंडलिंग नीति या कार्यप्रवाह नाम के आधार पर) के अंदर गतिशील संकल्प की आवश्यकता है, तो मैं lending IoC powers via the highly-specific providers

+0

लिंक के लिए धन्यवाद। जब मेरे पास समय होता है तो मुझे इसे और अधिक सावधानीपूर्वक पढ़ना पड़ता है, लेकिन मुझे लगता है कि मैंने ऐसा कुछ करने की कोशिश की, फिर इसके खिलाफ फैसला किया और आईओसी कंटेनर का उपयोग करने के बजाय गतिशील वस्तुओं को बनाने के लिए एक अमूर्त कारखाने का उपयोग किया। मैंने कारखाने को बनाने के लिए केवल कंटेनर का इस्तेमाल किया। ओपी के मूल परिदृश्य का उपयोग करते हुए – Mendelt

+2

@Rinat: आप ए में हैं, और आपको बी उदाहरणों की संख्या की आवश्यकता है। कंटेनर के संदर्भ में, आप अपने बीएस कैसे प्राप्त करते हैं? – flipdoubt

+0

आपका लिंक अब काम नहीं करता है ... क्या आप इसे अपडेट कर सकते हैं? –

1

विचार करने के लिए के रूप में एक @flipdoubt

हैं अप करने के लिए का पालन करें आप सेवा लोकेटर प्रकार पैटर्न का उपयोग करके समाप्त हो जाते हैं, जिसे आप http://www.codeplex.com/CommonServiceLocator देख सकते हैं। इसमें कई लोकप्रिय आईओसी फ्रेमवर्क (विंडसर, स्ट्रक्चरमैप) के लिए कुछ बाइंडिंग उपलब्ध हैं जो उपयोगी हो सकती हैं।

शुभकामनाएं।

+0

धन्यवाद! मैं इसे देख लूँगा। मैंने पाया कि अपने स्वयं के सेवा लोकेटर को बनाना वास्तव में आसान है, लेकिन मुझे विचार मिल सकता है कि उन्होंने चीजें कैसे कीं! – Mendelt

+0

कोई चिंता नहीं, शुभकामनाएं। – smaclell

1

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

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

CommonServiceLocator इस उद्देश्य के लिए नहीं है, हालांकि कोई इसका उपयोग करने के लिए लुभाने वाला हो सकता है। CommonServiceLocator का मुख्य उद्देश्य उन ऐप्स/ढांचे के लिए है जो क्रॉस आईओसी कंटेनर अनुपालन करना चाहते हैं। हालांकि, उपयोग करने वाले ऐप्स को घटक और उनके निर्भरताओं का पदानुक्रम बनाने के लिए केवल एक बार लोकेटर को कॉल करना चाहिए। इसे फिर से कभी नहीं बुलाया जाना चाहिए। अगर हमारे पास यह लागू करने का कोई तरीका था कि हमारे पास होगा। प्रिज्म (http://www.microsoft.com/compositewpf) में हमने मॉड्यूल बनाने के लिए एक आईसीओन्टैनरफेकैड पेश किया। यह एक निम्न स्तर वाला एक सेवा लोकेटर है। पीछे मुड़कर देखें तो हम शायद एक ModuleFactory या कुछ बनाया जाना चाहिए था और IContianerFacade इस्तेमाल किया यह भी नियंत्रण प्राप्त करने के लिए, और उसके बाद के लिए इस्तेमाल किया है कि संकल्प मॉड्यूल सीधे फसाड के लिए जा रहा बनाम। हिंदसाइट 20/20 है।यह कम स्तर पर्याप्त है हालांकि यह वास्तव में चीजों को प्रभावित नहीं करता है।

सीएसएल पर, हम नामकरण के साथ कुश्ती कर रहे थे क्योंकि इससे भ्रम पैदा हो सकता है। अंत में हमने सीएसएल पर फैसला किया क्योंकि तकनीकी रूप से इंटरफ़ेस आपके लिए DI करने के लिए नहीं था।

10

मैं इस पर निक ब्लूमहार्ट की मिनी-सीरीज़ की जांच करने की सिफारिश करता हूं।

http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx

+0

धन्यवाद! इसे मेरी पढ़ने की सूची में जोड़ा गया :-) – Mendelt

+0

यह एक उत्कृष्ट लेख था और मेरे लिए इस समस्या को स्पष्ट करने में मदद मिली! –

+0

लिंक पसंद आया। लेकिन मैं सिर्फ एक लिंक के बजाय एक उच्च स्तरीय सारांश पसंद करेंगे। – KFL

0

एक बहुत comon समस्या है कि। Typed Factory Facility में निर्मित विंडसर आपको उल्लिखित दोषों के बिना कारखाने का उपयोग करने का लाभ देगा।

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