Tech-Note For DKMILAN™

C#实现支持插件与二次开发的应用程序编写

五月 23rd, 2008 · 1 Comment

这两天一直在研究这个插件功能的实现,总结一些心得吧。

首先是应该定义插件应该实现的接口,接口里面是插件需要实现的功能与提供的内容。我是这么设计的:

首先是建立一个新的类库,用于把我们支持的插件的类型都以接口的形式放进去。比如我现在为我的Service Master设计了以下几个插件类型:外观插件,功能插件,系统信息插件,其他类型插件。目前接口设计如下

2008-5-24-0000

然后在原有的软件项目(ServiceMaster)中添加了一个插件检测的类,这个类用于检测已经放到Plugin文件夹下的插件。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Reflection;
  5. using System.IO;
  6. using System.Collections;
  7. namespace ServiceMaster
  8. {
  9.     public static class PluginCheck
  10.     {
  11.         public static IPluginMenu[] getAllPluginsMenu()
  12.         {
  13.             IPluginInfo[] plugins = getAllPluginsInfo();
  14.             List menus = new List();
  15.             foreach (IPluginInfo plugin in plugins)
  16.             {
  17.                 if (plugin is IPluginMenu)
  18.                 menus.Add((IPluginMenu)plugin);
  19.             }
  20.             return menus.ToArray();
  21.         }
  22.         public static IPluginInfo[] getAllPluginsInfo()
  23.         {
  24.             if (Directory.Exists(Directory.GetCurrentDirectory() + @"\Plugin"))
  25.             {
  26.                 string[] files = Directory.GetFiles(Directory.GetCurrentDirectory() + @"\Plugin");
  27.                 List dlls = new List();
  28.                 foreach(string file in files)
  29.                 {
  30.                     FileInfo info = new FileInfo(file);
  31.                     if (info.Extension == ".dll")
  32.                         dlls.Add(getPluginClass(info.Name, "PluginInfo"));
  33.                 }
  34.                 return dlls.ToArray();
  35.             }
  36.             else
  37.             {
  38.                 Directory.CreateDirectory(Directory.GetCurrentDirectory() + @"\Plugin");
  39.                 return new IPluginInfo[0];
  40.             }
  41.         }
  42.         public static IPluginInfo getPluginClass(string filename,string className)
  43.         {
  44.             Assembly ass = null;
  45.             try
  46.             {
  47.                 ass = Assembly.LoadFrom(@"plugin\" + filename);
  48.             }
  49.             catch (BadImageFormatException)
  50.             {
  51.                 return null;
  52.             }
  53.             string nspace=System.IO.Path.GetFileNameWithoutExtension(filename);
  54.             Type search = ass.GetType(nspace + "." + className);
  55.             if (search==null)
  56.             return null;
  57.             Object o = Activator.CreateInstance(search);
  58.             IPluginInfo info = (IPluginInfo)o;
  59.             return info;
  60.         }
  61.     }
  62. }

然后的工作就是就是编写插件了。

得益于.Net平台的CLR,在VS上写出的所有的类库都是可以用的,不管你是用C++还是C#还是其他

就以C#为例说一下写一个插件的步骤

  • 建一个类库
  • 在引用里面添加我们写好的PluginSupport.dll
  • 然后建一个类,类名一定是PluginInfo.cs。记得一定加上using ServcieMaster
  • 然后让这个类实现上面的任意一个或者多个继承于IPluginInfo的接口(也可以只实现IPluginSysInfo,但是那样的话我的ServiceMaster只能认出来是一个插件,但是没有实际功能)
  • 完善功能
  • 编译,生成DLL
  • 把生成的插件放到ServiceMaster的Plugin文件夹下
  • 运行ServiceMaster

这是一个示例的插件

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using ServiceMaster;
  5. using System.Reflection;
  6.  
  7. namespace testPlugin
  8. {
  9.     public class PluginInfo:IPluginMenu
  10.     {
  11.         #region IPluginInfo 成员
  12.  
  13.         string IPluginInfo.AutherWebUrl
  14.         {
  15.             get
  16.             {
  17.                 return "http://dkmilan.72pines.com";
  18.             }
  19.         }
  20.  
  21.         string IPluginInfo.Author
  22.         {
  23.             get
  24.             {
  25.                 return "DKMILAN";
  26.             }
  27.         }
  28.  
  29.         string IPluginInfo.Name
  30.         {
  31.             get
  32.             {
  33.                 return "TestPlugin";
  34.             }
  35.         }
  36.  
  37.         string IPluginInfo.Version
  38.         {
  39.             get { return "1.0.0.0"; }
  40.         }
  41.         #endregion
  42.  
  43.         #region IPluginMenu 成员
  44.  
  45.         System.Windows.Forms.ToolStripMenuItem IPluginMenu.PluginMenu
  46.         {
  47.             get
  48.             {
  49.                 System.Windows.Forms.ToolStripMenuItem MenuOne = new System.Windows.Forms.ToolStripMenuItem();
  50.                 System.Windows.Forms.ToolStripMenuItem MenuTwo = new System.Windows.Forms.ToolStripMenuItem();
  51.                 System.Windows.Forms.ToolStripMenuItem topMenu = new System.Windows.Forms.ToolStripMenuItem();
  52.                 //
  53.                 // MenuOne
  54.                 //
  55.                 MenuOne.Name = "MenuOne";
  56.                 MenuOne.Size = new System.Drawing.Size(148, 22);
  57.                 MenuOne.Text = "Hello!";
  58.                 MenuOne.Click += new System.EventHandler(MenuOne_Click);
  59.                 //
  60.                 // MenuTwo
  61.                 //
  62.                 MenuTwo.Name = "MenuTwo";
  63.                 MenuTwo.Size = new System.Drawing.Size(148, 22);
  64.                 MenuTwo.Text = "Hello 2~";
  65.                 MenuTwo.Click += new System.EventHandler(MenuTwo_Click);
  66.                 //
  67.                 // topMenu
  68.                 //
  69.                 topMenu.Name = "topMenu";
  70.                 topMenu.Size = new System.Drawing.Size(148, 22);
  71.                 topMenu.Text = "插件菜单";
  72.                 //
  73.                 topMenu.DropDownItems.Add(MenuOne);
  74.                 topMenu.DropDownItems.Add(MenuTwo);
  75.                 return topMenu;
  76.             }
  77.         }
  78.  
  79.         #endregion
  80.  
  81.         private void MenuOne_Click(object sender, EventArgs e)
  82.         {
  83.             System.Windows.Forms.MessageBox.Show("Enjoy ServiceMaster!");
  84.         }
  85.         private void MenuTwo_Click(object sender, EventArgs e)
  86.         {
  87.             System.Windows.Forms.MessageBox.Show("My Plugin!");
  88.         }
  89.     }
  90. }
Share : These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • blogmarks
  • Fleck
  • Gwar
  • Haohao
  • Simpy
  • Spurl
[]-[]-[]-[]-[]

Tags: .Net编程 · 系统服务优化专家

1 response so far ↓

Leave a Comment