2009-06-30 7 views
9

एक डिज़ाइन करने योग्य .NET घटक बनाते समय, आपको एक डिफ़ॉल्ट कन्स्ट्रक्टर प्रदान करना होगा। IComponent प्रलेखन से:निर्भरता इंजेक्शन के साथ डिजाइन करने योग्य घटकों को कैसे गठबंधन करें

एक घटक होने के लिए, एक वर्ग IComponent इंटरफ़ेस को लागू करना चाहिए और एक बुनियादी निर्माता कि कोई पैरामीटर या प्रकार IContainer की एक एकल पैरामीटर की आवश्यकता है प्रदान करते हैं।

यह रचनाकार तर्कों के माध्यम से निर्भरता इंजेक्शन करना असंभव बनाता है। (अतिरिक्त कंस्ट्रक्टर्स प्रदान की जा सकता है, लेकिन डिजाइनर उन्हें अनदेखा जाएगा।) कुछ विकल्प हम विचार कर रहे हैं:

  • सेवा लोकेटर

    निर्भरता इंजेक्शन का प्रयोग न करें, इसके बजाय सेवा लोकेटर पैटर्न का उपयोग निर्भरता हासिल करने के लिए। ऐसा लगता है कि IComponent.Site। GetService के लिए है। मुझे लगता है कि हम एक पुन: प्रयोज्य आईएसआईटी कार्यान्वयन (ConfigurableServiceLocator?) बना सकते हैं जिसे आवश्यक निर्भरताओं के साथ कॉन्फ़िगर किया जा सकता है। लेकिन यह एक डिजाइनर संदर्भ में कैसे काम करता है?

  • निर्भरता गुण

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

    एक प्रारंभ विधि

    इस के साथ

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

कोई विचार यह है कि सबसे अच्छा अभ्यास क्या है? आप इसे कैसे करते हो?


संपादित: मैं हटा दिया है "(उदाहरण, एक WinForms UserControl)" के बाद से मैं सवाल का इरादा सामान्य रूप में घटकों के बारे में माना जाता है। घटक नियंत्रण के उलटा होने के बारे में हैं (UMLv2 specification की धारा 8.3.1 देखें) इसलिए मुझे नहीं लगता कि "आपको किसी भी सेवा को इंजेक्ट नहीं करना चाहिए" एक अच्छा जवाब है।


संपादित 2: यह अंत में करने के लिए मार्क का जवाब "मिल" WPF और MVVM पैटर्न के साथ कुछ खेल लिया। अब मैं देखता हूं कि दृश्य नियंत्रण वास्तव में एक विशेष मामला है। डिजाइनर सतहों पर गैर-दृश्य घटकों का उपयोग करने के लिए, मुझे लगता है कि .NET घटक मॉडल मूल रूप से निर्भरता इंजेक्शन के साथ असंगत है। ऐसा लगता है कि इसके बजाय सेवा लोकेटर पैटर्न के आसपास बनाया गया है। शायद यह System.ComponentModel.Composition नामस्थान में .NET 4.0 में जोड़े गए बुनियादी ढांचे के साथ बदलना शुरू कर देगा।

उत्तर

6

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

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

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

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

विंडोज़ फॉर्म में, आप अभी भी नियंत्रण में डेटा संदर्भ निर्दिष्ट करके ऐसा ही कर सकते हैं। अनिवार्य रूप से, यह संपत्ति इंजेक्शन है - बस जागरूक रहें कि आपको सेवाओं को इंजेक्ट नहीं करना चाहिए; आपको डेटा इंजेक्ट करना चाहिए।

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

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

+0

यदि मैं आपका उत्तर सही तरीके से व्याख्या कर रहा हूं, तो आप कह रहे हैं कि नियंत्रण किसी भी सेवा का उपयोग नहीं करना चाहिए। मुझे यकीन नहीं है कि मैं सहमत हूं। उदाहरण के लिए, मेरे पास एक नियंत्रण है जो System.Windows.Forms.TextRenderer को कॉल करके सीधे टेक्स्ट प्रस्तुत नहीं करता है। इसके बजाए, यह एक इंजेक्शन योग्य ITextRenderer सेवा का उपयोग करता है (मूल रूप से वही विधियों के साथ)। यह मुझे .NET फ्रेमवर्क द्वारा प्रदान की गई चीज़ों से परे फैंसी संक्षेप रणनीतियों को लागू करने की अनुमति देता है, जबकि इस तरह के कोड को नियंत्रण से स्वतंत्र रखते हुए। –

+0

हां, मैं कह रहा हूं कि नियंत्रणों को कोई सेवाओं का उपयोग नहीं करना चाहिए - सेवाओं को नियंत्रणों का उपयोग करना चाहिए। नियंत्रण को यूआई प्रस्तुत करने के अलावा कुछ भी नहीं करना चाहिए। यह ठीक है कि आप फैंसी संक्षेप रणनीतियों को इंजेक्ट कर सकते हैं, लेकिन इस तरह का तर्क दृश्य (दृश्य) मॉडल में है, न कि दृश्य में। इसके बाद आप मॉडल पर गुणों के लिए अपने दृश्य को डेटाबेस कर सकते हैं जो इंजेक्शन निर्भरताओं का आह्वान करके वांछित मूल्यों का उत्पादन कर सकते हैं। भले ही आप WinForms का उपयोग कर रहे हों, प्रेरणा के लिए इसे देखें: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx –

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