简要说明:可扩展程序包括三个部分,第一部分是个接口程序,包含IAppFunctionality接口,所有扩展都要实现该接口,第二部分是扩展,实现IAppFunctionality,第三部分是主程序,它检测与它同级目录下是否有plugins文件夹,如果没有,就创建,如果有,查找该目录下所有实现IAppFunctionality接口的程序集,并更新菜单。
未添加扩展(即plugins下无dll程序)的运行情况
安装插件之后
点击Plugin1和Plugin2:
程序源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//AuthorInfoAttribute.cs using System; namespace PluginBase { public interface IAppFunctionality { void ShowInfo(); } [AttributeUsage(AttributeTargets.Class)] public class AuthorInfoAttribute : System.Attribute { public string Email { get; set; } public string Name { get; set; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//Plugin1.cs using System.Windows.Forms; using PluginBase; namespace Plugin1 { [AuthorInfoAttribute(Name="liulixiang", Email="liulixiang1988@gmail.com")] public class Plugin1: IAppFunctionality { public void ShowInfo() { MessageBox.Show("Hello world, 你懂的。"); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//Plugin2.cs using System.Windows.Forms; using PluginBase; namespace Plugin2 { [AuthorInfoAttribute(Name="liulixiang", Email="liulixiang1988@gmail.com")] public class Plugin2:IAppFunctionality { public void ShowInfo() { MessageBox.Show("打酱油~~~"); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
//MainApp.cs using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Windows.Forms; using PluginBase; namespace MyExtendableApp { public partial class MainApp : Form { private string pluginDir = "plugins\\"; private List<PluginBase.IAppFunctionality> apps = new List<PluginBase.IAppFunctionality>(); public MainApp() { InitializeComponent(); LoadPlugins(); } private void LoadPlugins() { if (!Directory.Exists(pluginDir)) { // 如果扩展程序文件夹不存在,就创建它 Directory.CreateDirectory(pluginDir); } try { var plugins = from plugin in Directory.EnumerateFiles(pluginDir, "*.dll") select plugin; foreach (string plugin in plugins) { Assembly thePluginAsm = null; thePluginAsm = Assembly.LoadFrom(plugin); //获取所有实现扩展接口的程序集 var theClassTypes = from t in thePluginAsm.GetTypes() where t.IsClass && (t.GetInterface("IAppFunctionality") != null) select t; //调用接口方法 foreach (Type t in theClassTypes) { IAppFunctionality itfApp = (IAppFunctionality)thePluginAsm.CreateInstance(t.FullName, true); apps.Add(itfApp); ToolStripMenuItem menuItem = new ToolStripMenuItem(t.Name); menuItem.Click += new System.EventHandler(delegate(object o, EventArgs e) { itfApp.ShowInfo(); }); menuStrip1.Items.Add(menuItem); // itfApp.ShowInfo(); } } } catch (System.Exception ex) { MessageBox.Show(ex.Message); } } } } |