2009-07-01 11 views
28

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

मुझे मिल गया है (अभी तक एटीएम, कुछ भी कार्यान्वित किया जाता है) आधार "IPlugin" इंटरफेस लिखा

यहाँ कैसे मैं लोड हो रहा है कर रहा हूँ है:

public static void Load() 
{ 
    // rawr: http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx 
    String[] pluginFiles = Directory.GetFiles(Plugins.PluginsDirectory, "*.dll"); 
    foreach (var plugin in pluginFiles) 
    { 
     Type objType = null; 
     try 
     { 
      //Assembly.GetExecutingAssembly().GetName().Name 
      MessageBox.Show(Directory.GetCurrentDirectory()); 
      Assembly asm = Assembly.Load(plugin); 
      if (asm != null) 
      { 
       objType = asm.GetType(asm.FullName); 
       if (objType != null) 
       { 
        if (typeof(IPlugin).IsAssignableFrom(objType)) 
        { 
         MessageBox.Show(Directory.GetCurrentDirectory()); 
         IPlugin ipi = (IPlugin)Activator.CreateInstance(objType); 
         ipi.Host = Plugins.m_PluginsHost; 
         ipi.Assembly = asm; 
        } 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(e.ToString(), "Unhandled Exception! (Please Report!)", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information); 
     } 
    } 
} 

एक दोस्त ने मदद करने के लिए कोशिश की, लेकिन मैं वास्तव में समझ में नहीं आया कि क्या गलत था।

प्लगइन्स के लिए फ़ोल्डर संरचना है निम्नलिखित:

\
\ प्लगइन्स \

सभी प्लगइन्स एक .dll "Lab.Core.dll" कहा जाता है को संदर्भित [जड़] निर्देशिका में है और यह डुप्लिकेट संदर्भ लोड होने के कारण प्लगइन्स निर्देशिका में मौजूद नहीं है।

प्लगइन सिस्टम Lab.Core.dll से लोड किया गया है जिसे मेरे निष्पादन योग्य द्वारा भी संदर्भित किया जाता है। "IPlugin" टाइप करें Lab.Core.dll में भी है। Lab.Core.dll, जैसा कि नाम दिया गया है, मेरे आवेदन का मूल है।

संपादित करें:

प्रश्न: क्यों/क्या है कि अपवाद मैं हो रही है और मैं इसे ठीक करने के बारे में कैसे जा सकते हैं?

अंतिम संपादन:

ठीक है तो मैं यह कुछ स्रोत कोड एक दोस्त एक TF2 नियामक के लिए लिखा था देखने के बाद फिर से लिखने का फैसला किया।

यहाँ मैं क्या मिला है और यह काम करता है:

public class TestPlugin : IPlugin { 
    #region Constructor 

    public TestPlugin() { 
     // 
    } 

    #endregion 

    #region IPlugin Members 

    public String Name { 
     get { 
      return "Test Plugin"; 
     } 
    } 

    public String Version { 
     get { 
      return "1.0.0"; 
     } 
    } 

    public String Author { 
     get { 
      return "Zack"; 
     } 
    } 

    public Boolean OnLoad() { 
     MessageBox.Show("Loaded!"); 
     return true; 
    } 

    public Boolean OnAllLoaded() { 
     MessageBox.Show("All loaded!"); 
     return true; 
    } 

    #endregion 
} 

     public static void Load(String file) { 
     if (!File.Exists(file) || !file.EndsWith(".dll", true, null)) 
      return; 

     Assembly asm = null; 

     try { 
      asm = Assembly.LoadFile(file); 
     } catch (Exception) { 
      // unable to load 
      return; 
     } 

     Type pluginInfo = null; 
     try { 
      Type[] types = asm.GetTypes(); 
      Assembly core = AppDomain.CurrentDomain.GetAssemblies().Single(x => x.GetName().Name.Equals("Lab.Core")); 
      Type type = core.GetType("Lab.Core.IPlugin"); 
      foreach (var t in types) 
       if (type.IsAssignableFrom((Type)t)) { 
        pluginInfo = t; 
        break; 
       } 

      if (pluginInfo != null) { 
       Object o = Activator.CreateInstance(pluginInfo); 
       IPlugin plugin = (IPlugin)o; 
       Plugins.Register(plugin); 
      } 
     } catch (Exception) { 
     } 
    } 

    public static void LoadAll() { 
     String[] files = Directory.GetFiles("./Plugins/", "*.dll"); 
     foreach (var s in files) 
      Load(Path.Combine(Environment.CurrentDirectory, s)); 

     for (Int32 i = 0; i < Plugins.List.Count; ++i) { 
      IPlugin p = Plugins.List.ElementAt(i); 
      try { 
       if (!p.OnAllLoaded()) { 
        Plugins.List.RemoveAt(i); 
        --i; 
       } 
      } catch (Exception) { 
       Plugins.List.RemoveAt(i); 
       --i; 
      } 
     } 
    } 
+2

है कि मैं ध्यान दें कि आप वास्तव में सवाल नहीं पूछा है, तो आप सिर्फ का वर्णन किया है तुम क्या करने की कोशिश कर रहे क्या इन 2 इंटरफेस का उपयोग करें। क्या आप अपने प्रश्न को प्रश्न के रूप में वाक्यांश दे सकते हैं? –

+1

एरर। क्षमा करें, यह समझाने की कोशिश कर रहा था कि मैं क्या कर रहा था लेकिन सवाल भूल गया। : एक्स मैं इसे संपादित कर दूंगा। – Zack

+1

कृपया प्राप्त पूर्ण अपवाद पोस्ट करें, स्टैक ट्रेस और किसी भी आंतरिक अपवाद के साथ पूरा करें। Ex.ToString() के परिणाम पोस्ट करें। –

उत्तर

7

ऐसा लगता है कि आप एक परिपत्र संदर्भ है। आपने कहा कि आपके प्लगइन्स संदर्भ Lab.Core.DLL का संदर्भ देते हैं, लेकिन आप यह भी कहते हैं कि प्लगइन Lab.Core.DLL से लोड किए गए हैं।

क्या मैं गलत समझ रहा हूं कि यहां क्या हो रहा है?

संपादित करें: ठीक है अब है कि आप सवाल का सवाल ...

जोड़ लिया है आप Lab.Core.DLL के लिए प्लगइन के लिए सुलभ लोड किए जाने के बाद से यह एक निर्भरता है की जरूरत है। आम तौर पर इसका मतलब यह होगा कि इसे एक ही निर्देशिका में या जीएसी में रखा जाए।

मुझे संदेह है कि यहां खेलने पर गहरे डिजाइन मुद्दे हैं, लेकिन यह आपकी तत्काल समस्या है।

+0

सहायता के लिए धन्यवाद। मैंने इसे एक दोस्त के सॉस कोड के आधार पर फिर से लिखना समाप्त कर दिया। मेरा समाधान शामिल करने के लिए मूल पोस्ट संपादित किया गया। :) – Zack

28

प्रबंधित तानाना फ्रेमवर्क (MEF) नेट कि अनुप्रयोगों और घटकों के अधिक से अधिक पुन: उपयोग के लिए सक्षम बनाता है में एक नए पुस्तकालय है। एमईएफ का उपयोग करके, .NET अनुप्रयोग गतिशील रूप से रचित रूप से संकलित होने से शिफ्ट को स्थानांतरित कर सकते हैं। यदि आप एक्स्टेंसिबल एप्लिकेशन, एक्स्टेंसिबल फ्रेमवर्क और एप्लिकेशन एक्सटेंशन बना रहे हैं, तो एमईएफ आपके लिए है।

http://www.codeplex.com/MEF

संपादित करें: CodePlex दूर जा रहा है - कोड केवल अभिलेखीय प्रयोजनों के लिए Github ले जाया गया है: https://github.com/MicrosoftArchive/mef

+4

इसे कोडप्लेक्स में ले जाया गया था: http://www.codeplex.com/ एमईएफ –

+1

यह एमईएफ के उपयोग के बिना वास्तव में संभव होना चाहिए। –

+10

बेशक यह एमईएफ के उपयोग के बिना संभव है। एमईएफ में जादू कुछ भी नहीं है। लेकिन एमईएफ कई वर्षों में प्लगइन आर्किटेक्चर में विशेषज्ञों द्वारा डिजाइन और कार्यान्वित किया गया था। (मैंने 2004 आईआईआरसी में एमईएफ के शुरुआती डिजाइन पर थोड़ा सा काम किया था।) आप वास्तव में इस जगह में प्रो आर्किटेक्ट्स द्वारा पांच साल के काम के प्रयास को डुप्लिकेट करने का प्रयास करना चाहते हैं? –

6

एक तरफ जवाब के रूप में, मैं लागू करने

///<summary> 
///</summary> 
public interface IPlugin { 
    ///<summary> 
    ///</summary> 
    string Name { get; } 
    ///<summary> 
    ///</summary> 
    string Description { get; } 
    ///<summary> 
    ///</summary> 
    string Author { get; } 
    ///<summary> 
    ///</summary> 
    string Version { get; } 

    ///<summary> 
    ///</summary> 
    IPluginHost Host { get; set; } 

    ///<summary> 
    ///</summary> 
    void Init(); 
    ///<summary> 
    ///</summary> 
    void Unload(); 

    ///<summary> 
    ///</summary> 
    ///<returns></returns> 
    IDictionary<int, string> GetOptions(); 
    ///<summary> 
    ///</summary> 
    ///<param name="opcion"></param> 
    void ExecuteOption(int option); 

} 



///<summary> 
///</summary> 
public interface IPluginHost { 
    ///<summary> 
    ///</summary> 
    IDictionary<string, object> Variables { get; } 
    ///<summary> 
    ///</summary> 
    ///<param name="plugin"></param> 
    void Register(IPlugin plugin); 
} 
संबंधित मुद्दे