我的網誌清單

2013年11月13日 星期三

C# PlugIn 的設計 方法

要怎樣設計一個 PlugIn 的程式架構呢?

這個之前就有一直在研究 , 不過這次是在  C# 的平台上實現它 ,

首先這次的架構是 , 可以有一個類別 然後定義好一連串共用的類別

再把這個類別寫在另一個DLL , 需要使用時再去載入他,使用他 , 架構如下






MainLib 載入
Game001.dll
Game002.dll

然後再依照邏輯去使用他




==========================================

首先我們先設計  PlugIn 的模型 出來 ,

我們設計了一個 PluginSkeleon ,裡面讓繼承的人去實作他 , 另外他們所參考的  些類別都是從

主類別所引用 

這裡需要其中一個技術的了解是 , 要會 XML設定檔讀取 , 因為現在大家都在用,而且
去讀設定檔來做 , 比較有彈性

範例 XML
<List>
    <dog name="PortTester" enabled="true" sleepTime="60">
      <plugin type="Plug.Class1,Plug">
        <parameter name="Hosts" value="127.0.0.1"/>
      </plugin>
    </dog>
</List>

這裡也講一下 XML  讀取的部份 

首先要引用這二個
using System.Configuration;
using System.Xml;
                                             然後 宣告
 System.Configuration.Configuration config =
                ConfigurationManager.OpenExeConfiguration(
                    ConfigurationUserLevel.None);
                                    
然後指定要去讀取 List 區段 , 底下這一段程式就可以指定讀取XML區塊了
 ConfigurationSection ss=  config.GetSection("List");                                
           XmlDocument doc = new XmlDocument();                                
           doc.LoadXml(ss.SectionInformation.GetRawXml());                                
                                    
//這裡指定要讀取 List 底下的 dog 的區段  XML                                                                
 XmlNodeList NodeLists = doc.SelectNodes("List/dog");                                                                
                                    
//這裡是把所有 "List/dog" 區段讀進來                                                                                                
  foreach (XmlNode OneNode in NodeLists)                                                                
           {                                                                                                                                
              //然後這裡是取 Name 的屬性                                                                 
               String name = OneNode.Attributes["name"].Value;                                                                
                                                                                                                                                                
               //這裡是是要再深下去讀PlugIn 的所有項目                                                                
               var plugins = OneNode.SelectNodes("plugin");                                                                
                                    
                                    
               foreach (XmlNode p in plugins)                                                                
               {                                     
                   var type = p.Attributes["type"].Value;                                                                
                                    
                   Console.WriteLine("--"+type);                                                                                                
                                    
                     //再下一層的 Section                                                                                                
                   var parameters = p.SelectNodes("parameter");                                                                
                   foreach (XmlNode g in parameters)                                                                
                   {                                                                                                                                
                       var type_test = g.Attributes["name"].Value;                                                                
                       Console.WriteLine("      "+type_test);                                                                
                   }                                                                                                                                
                                    
               }                                                                                                                                
                                    
           }                                                                                                


接下是把要載入的DLL 寫成一個類別 讓程式可以去入DLL 

   
     public static object Create(string typeName)
        {
            Type pluginType;

            try
            {
                pluginType = Type.GetType(typeName, true);
            }
            catch (Exception ex)
            {
                throw new ArgumentException(String.Format("The plugin type named {0} could not be loaded.", typeName), ex);
            }

            var argumentlessContructor = pluginType.GetConstructor(Type.EmptyTypes);

            if (argumentlessContructor == null)
                throw new ArgumentException(String.Format("The plugin of type {0} should define an argumentless constructor to be created.", typeName));

            return argumentlessContructor.Invoke(null);
        }

        public Iplugin GetPlug(string Classname)
        {
            return (Iplugin)Create(Classname);
        }

使用方法則是 把要載入的DLL 放到跟程式同一個目錄

然後   
       傳入的參數規則是 ("namespace名稱.物件名稱,namespace名稱")
    Iplugin test = GetPlug("Plug.Class1,Plug");


之後我還有寫一個管理的介面可以管理這些被載入的 DLL , 做控管 
Collection   ,以確保我的程式不會太過複雜






沒有留言:

張貼留言