做winform程序,很多时候都需要用到插件式的,所以本人做了一个Demo,思路跟网上思路基本一致,现在共享出来如有需要的朋友可以下载。 申明:部分代码来源于网上,当然思路也是,呵呵 原理很简单: 一:定义插件接口 二:实现插件接口并建立不同工项目,使其在生成时生成不同的DLL 三:主程序运行时根据接口名利用反射对插件目录的DLL进行加载,加载完成后便可以使用插件接口定义的方法或属性了。 下面上几张图,有兴趣的朋友可以先看看,觉得值得一看的朋友可以下载。 项目结构: DefaultPlugin,PosPlugin两个项目均为插件,均实现了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; } } } 此图现在有两个插件 运行效果如下
|
|
来自: ThinkTank_引擎 > 《插件化开发》