2010-04-29 12 views
22

अपने कोड में एमईएफ का उपयोग करने के लिए कुछ सर्वोत्तम अभ्यास क्या हैं? क्या आपके एक्स्टेंसिबल एप्लिकेशन को शुरू करते समय ध्यान में रखना कोई समस्या है? क्या आप किसी भी चीज में भाग गए थे जिसे आपको पहले जाना चाहिए था?एमईएफ सर्वोत्तम प्रथाओं क्या हैं?

उत्तर

7

मैं MEF पर एक पूरी तरह से विकसित एक्स्टेंसिबल आवेदन के निर्माण (और MVVM पैटर्न के साथ WPF का प्रयोग करके) के बीच में हूँ । मैंने मूल अनुप्रयोग ढांचा लिया जो मैंने बनाया और इसे SoapBox Core के रूप में सोर्स किया। मैंने कोड प्रोजेक्ट पर सोपबॉक्स कोर ओवर के आधार पर एक डेमो भी प्रकाशित किया: Building an Extensible Application with MEF, WPF, and MVVM

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

जहां तक ​​सर्वोत्तम प्रथाओं ... मैंने एक्सटेंशन का घोंसलाबद्ध पदानुक्रम बनाया है (इसलिए मूल मॉड्यूल को होस्ट कहा जाता है, और यह सब कुछ करता है और कुछ बुनियादी एक्सटेंशन आयात करता है)। फिर वे एक्सटेंशन अन्य एक्सटेंशन पॉइंट्स का पर्दाफाश करते हैं और जब आप इसे चलाते हैं तो अनुप्रयोग प्रकार स्वयं बनाता है (रचना और एक्सटेंशन के बीच एक क्रॉस)।

सबकुछ सीधे रखने के लिए, मैंने विस्तार पदानुक्रम स्थिर वर्गों के एक सेट में रखा है।

namespace SoapBox.Core.ExtensionPoints 
{ 
    public static class Host 
    { 
     public const string Styles = "ExtensionPoints.Host.Styles"; 
     public const string Views = "ExtensionPoints.Host.Views"; 
     public const string StartupCommands = "ExtensionPoints.Host.StartupCommands"; 
     public const string ShutdownCommands = "ExtensionPoints.Host.ShutdownCommands"; 
    } 
    public static class Workbench 
    { 
     public const string ToolBars = "ExtensionPoints.Workbench.ToolBars"; 
     public const string StatusBar = "ExtensionPoints.Workbench.StatusBar"; 
     public const string Pads = "ExtensionPoints.Workbench.Pads"; 
     public const string Documents = "ExtensionPoints.Workbench.Documents"; 

     public static class MainMenu 
     { 
      public const string Self = "ExtensionPoints.Workbench.MainMenu"; 
      public const string FileMenu = "ExtensionPoints.Workbench.MainMenu.FileMenu"; 
      public const string EditMenu = "ExtensionPoints.Workbench.MainMenu.EditMenu"; 
      public const string ViewMenu = "ExtensionPoints.Workbench.MainMenu.ViewMenu"; 
      public const string ToolsMenu = "ExtensionPoints.Workbench.MainMenu.ToolsMenu"; 
      public const string WindowMenu = "ExtensionPoints.Workbench.MainMenu.WindowMenu"; 
      public const string HelpMenu = "ExtensionPoints.Workbench.MainMenu.HelpMenu"; 
     } 
    } 

    public static class Options 
    { 
     public static class OptionsDialog 
     { 
      public const string OptionsItems = "ExtensionPoints.Options.OptionsDialog.OptionsItems"; 
     } 
    } 
} 

तो अगर आप फ़ाइल मेनू के लिए कुछ जोड़ने के लिए अपने विस्तार चाहते हैं तो आप कुछ है कि IMenuItem के साथ अनुबंध के नाम SoapBox.Core लागू करता निर्यात होगा: उदाहरण के लिए, यहाँ सब विस्तार अंक कि कोर रूपरेखा प्रदान करता है कर रहे हैं। ExtensionPoints.Workbench.MainMenu.FileMenu

प्रत्येक एक्सटेंशन में एक "आईडी" है जो केवल एक स्ट्रिंग पहचानकर्ता है। ये मौजूदा आईडी एक और पदानुक्रम में परिभाषित कर रहे हैं:

namespace SoapBox.Core.Extensions 
{ 
    public static class Workbench 
    { 
     public static class MainMenu 
     { 
      public const string File = "File"; 
      public const string Edit = "Edit"; 
      public const string View = "View"; 
      public const string Tools = "Tools"; 
      public const string Window = "Window"; 
      public const string Help = "Help"; 

      public static class FileMenu 
      { 
       public const string Exit = "Exit"; 
      } 

      public static class ViewMenu 
      { 
       public const string ToolBars = "ToolBars"; 
      } 

      public static class ToolsMenu 
      { 
       public const string Options = "Options"; 
      } 
     } 
    } 
} 

आप FileMenu देख सकते हैं पहले से ही बाहर निकलें विस्तार (कि ऐप को बंद करने के लिए पूर्व प्रोग्राम किया जाता) शामिल हैं। यदि आप फ़ाइल मेनू में कोई एक्सटेंशन जोड़ना चाहते हैं तो शायद आप इसे बाहर निकलें मेनू आइटम से पहले दिखाना चाहते हैं। IMenuItem IExtension है, जो दो गुण है से विरासत:

  • InsertRelativeToID
  • BeforeOrAfter

तो अपने विस्तार InsertRelativeToID के लिए SoapBox.Core.Extensions.Workbench.MainMenu.FileMenu.Exit हो जाएंगे और होगा पहले से पहले संपत्ति (एक गणना) के लिए वापस लौटें। जब वर्कबेंच सभी फ़ाइल मेनू एक्सटेंशन आयात करता है, तो यह इन आईडी के आधार पर सब कुछ टाइप करता है। इस तरह, बाद के एक्सटेंशन मौजूदा एक्सटेंशन के सापेक्ष खुद को सम्मिलित करते हैं।

6

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

ऐसे मामलों में जो सिंगलटन मॉडल आपके लिए उपयुक्त नहीं है, बिल्डर पैटर्न (वास्तविक तात्कालिकता से निर्यात किए गए हिस्से को अलग करने के लिए) का उपयोग करने की अनुशंसा की जाती है। आपको याद रखना चाहिए कि गैर साझा मॉडल का उपयोग करना काफी महंगा है क्योंकि यह वास्तविक त्वरण के लिए प्रतिबिंब का उपयोग कर रहा है (बिल्डर पैटर्न का उपयोग करके आप कम दर्द के साथ एक ही परिणाम प्राप्त कर सकते हैं)।

इसके अलावा यहां देखने http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/09/mef-for-beginner-toc.aspx और cource की आप जानते हैं कि तुम यहाँ जानकारी प्राप्त कर सकते हैं कि: http://mef.codeplex.com

2

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

सबसे पहले, जब आप एमईएफ के साथ काम कर रहे हैं, तो मैं केवल असेंबली के संदर्भ जोड़ने के बजाय, सिस्टम.कंपोनेंट मॉडेल को आपके समाधान में जोड़ने की सलाह देता हूं। यद्यपि एमईएफ में डीबगिंग मुद्दे एक पुनरावर्ती दुःस्वप्न की तरह महसूस करते हैं, लेकिन यह बिल्कुल अपरिहार्य और महत्वपूर्ण है जब आप यह नहीं समझ सकते कि क्या गलत हो रहा है।

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

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

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

अद्यतन 2010-06-09

मैं मदद से आप MEF झाड़ी का जंगल माध्यम से नेविगेट के लिए एक और संभव अभ्यास जोड़ना चाहते हैं। आज, मुझे उस परियोजना पर एक सैनिटी चेक करने की ज़रूरत है जिसे मैं "समझ नहीं पाया", इसलिए मैंने एक सरल, अपरंपरागत यूएमएल कक्षा आरेख को मार दिया जहां मैंने आयात और निर्यात को चिह्नित करने के लिए निर्भरताओं का उपयोग किया। यहां मुझे जो मिला है, जिसने इस मुद्दे को बहुत स्पष्ट बना दिया।

कार्य आवेदन: alt text

गैर काम आवेदन: alt text

कि बेवकूफ नहीं है? मॉडल लोड नहीं किया गया था, और यह एक द्वीप पर ही था। I मानते हैं यही कारण है कि मेरी एमईएफ-आधारित निर्भरताओं को हल नहीं किया जा रहा है (अगर कोई मुझे गलत कर सकता है तो मैं इसे दूषित कर सकता हूं, हालांकि मैं इसकी सराहना करता हूं!)

+2

आपकी छवियां टूट गई हैं। –

+0

उह ... मैंने अपने खाते से कुछ छवियों को मंजूरी दे दी होगी। मुझे मूल की तलाश करनी होगी। मुझे बताने के लिए धन्यवाद। – Dave

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