做winform程序,很多時候都需要用到插件式的,所以本人做了一個Demo,,思路跟網(wǎng)上思路基本一致,,現(xiàn)在共享出來如有需要的朋友可以下載,。 申明:部分代碼來源于網(wǎng)上,當(dāng)然思路也是,,呵呵 原理很簡單: 一:定義插件接口 二:實現(xiàn)插件接口并建立不同工項目,,使其在生成時生成不同的DLL 三:主程序運(yùn)行時根據(jù)接口名利用反射對插件目錄的DLL進(jìn)行加載,,加載完成后便可以使用插件接口定義的方法或?qū)傩粤恕?/p> 下面上幾張圖,,有興趣的朋友可以先看看,覺得值得一看的朋友可以下載,。 項目結(jié)構(gòu): DefaultPlugin,PosPlugin兩個項目均為插件,,均實現(xiàn)了Iplugin接可 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Windows.Forms; namespace WinDemo.Core { public interface Iplugin { PluginInfoAttribute PluginInfo { get; set; } bool IsLoad { get; set; } Image ModulePicture { get; } Image ModulePictureEnter { get; } Image ModulePictureClick { get; } string ModuleName { get; } Dictionary<string, EventHandler> ChildNodes { get; } ILoadForm FormLoader { get; set; } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.IO; using System.Windows.Forms; using System.Collections; namespace WinDemo.Core { public static class PluginLoader { public static List<Iplugin> plugins = new List<Iplugin>(); private static ArrayList piProperties = new ArrayList(); private static bool IsValidPlugin(Type t) { bool ret = false; Type[] interfaces = t.GetInterfaces(); foreach( Type theInterface in interfaces ) { if (theInterface.FullName == "WinDemo.Core.Iplugin") { ret = true; break; } } return ret; } public static void LoadAllPlugins() { string[] files = Directory.GetFiles(Application.StartupPath + "\\plugin\\"); int i = 0; PluginInfoAttribute typeAttribute = new PluginInfoAttribute(); foreach (string file in files) { string ext = file.Substring(file.LastIndexOf(".")); if (ext != ".dll") continue; try { Assembly tmp = Assembly.LoadFile(file); Type[] types = tmp.GetTypes(); bool ok = false; foreach (Type t in types) if (IsValidPlugin(t)) { Iplugin plugin = (Iplugin)tmp.CreateInstance(t.FullName); plugins.Add(plugin); object[] attbs = t.GetCustomAttributes(typeAttribute.GetType(), false); PluginInfoAttribute attribute = null; foreach (object attb in attbs) { if (attb is PluginInfoAttribute) { attribute = (PluginInfoAttribute)attb; attribute.Index = i; i++; ok = true; break; } } if (attribute != null) { piProperties.Add(attribute); plugin.PluginInfo = attribute; } else throw new Exception("未定義插件屬性"); if (ok) break; } } catch (Exception err) { throw err; } } plugins.Sort((p1, p2) => { return p2.PluginInfo.Index - p1.PluginInfo.Index; }); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using WinDemo.Core; using System.Windows.Forms; namespace DefaultPlugin { [PluginInfo("Default","1.0","XH","www.cnporter.com",true,2)] public class Default : WinDemo.Core.Iplugin { private Dictionary<string, EventHandler> _ChildNodes = new Dictionary<string, EventHandler>(); private LeftNav frmLeftNav = new LeftNav(); public static ILoadForm Formloader ; public Default() { _ChildNodes.Add("菜單五", (sender,e) => { MessageBox.Show(sender.ToString()); }); _ChildNodes.Add("菜單四", (sender, e) => { MessageBox.Show(sender.ToString()); }); _ChildNodes.Add("菜單三", (sender, e) => { MessageBox.Show(sender.ToString()); }); _ChildNodes.Add("菜單二", (sender, e) => { MessageBox.Show(sender.ToString()); }); _ChildNodes.Add("菜單一", (sender, e) => { FormLoader.LoadNavFrm(frmLeftNav); }); } public Image ModulePicture { get { return ((System.Drawing.Image)(ImageResource.Index)); } } public Image ModulePictureEnter { get { return ((System.Drawing.Image)(ImageResource.IndexEnter)); } } public Image ModulePictureClick { get { return ((System.Drawing.Image)(ImageResource.IndexClick)); } } public string ModuleName { get { return "首頁"; } } public Dictionary<string, EventHandler> ChildNodes { get { return _ChildNodes; } } public bool IsLoad { get; set; } public ILoadForm FormLoader { get { return Formloader; } set { Formloader = value; } } public PluginInfoAttribute PluginInfo { get; set; } } } 此圖現(xiàn)在有兩個插件
運(yùn)行效果如下
|
|