最近自己用c#做了一个桌面的应用程序,寻思着一个小应用太没意思了,怎么才能做到可扩展呢,自然而然就想到了插件技术。现在很多软件都会使用插件技术,向eclipse,vs,google桌面等,最大的好处就是实现了应用程序的可扩展性,用户如果想扩展自己的应用,不用再打开工程重新编译,而只需按照一定的要求(插件协议)编写插件,然后通过安装等方法整合到系统中就可以做到“即插即用,无需编译”了,即所谓的插件。
其实插件技术最重要的就是解决插件和主程序(平台)互相通信的问题。一方面插件必须遵循一定的规范,即接口,在c#里,可以让插件的入口类EntryClass: Iplugin接口,在接口中,可以定义一些你需要插件实现的方法,比如Install方法,在插件安装的时候调用,Init方法,在插件初始化的时候调用,Uninstall方法,在插件卸载的时候调用等等。
- interface IPlugin
- {
- void Install();
- void Init();
- void Uninstall();
- }
当然,上面说的是主程序调用插件的方法,插件有时也会调用主程序的方法,这个差不多就是平常说的很多的Open API,很多应用或者平台都提供Open API,让用户能够在自己的应用中使用某种特定的功能,这个就相当于系统的接口。
- public void AddMenuStrip(String pluginName,String text,String eventHandlerName)
- {
- XmlDocument pluginConfig = new XmlDocument();
- pluginConfig.Load(Application.StartupPath + "//" + "plugin_config.xml");
- XmlNode rootNode = pluginConfig.SelectSingleNode("plugin");
- XmlNode thisNode = rootNode.SelectSingleNode(pluginName);
- XmlElement menuElement = pluginConfig.CreateElement("menuStrip");
- menuElement.SetAttribute("text",text);
- thisNode.AppendChild(menuElement);
- pluginConfig.Save(Application.StartupPath + "//" + "plugin_config.xml");
- //menuElement.SetAttribute("eventHandler", eventHandlerName);//事件处理函数名称
- }
我的“Open API”(如上)是通过修改系统的配置文件来实现的,上面的函数让用户可以给自己的插件定制主界面上的菜单入口。当然还会有很多其他方法,比如通过反射机制什么的。
协议定好了以后,就要想想具体的实现方式了,我觉得所有人都会第一时间想到DLL-dynamic link library,既然插件是动态的,那么用dll就是理所当然了。不过这里还有一个问题,用c#的反射机制,即assembly方法,可以很容易加载dll,然而想要不退出程序而卸载dll的话,就不那么容易了,网上有很多关于这个问题的帖子,也有讨论为什么微软不提供assembly.unload方法的。要想实现动态卸载,就要用appdomain技术了(关于这个理解不深)。
实现的技术也掌握了的话,就可以“折腾”自己的插件了。首先,你可以把插件需要的东西打包成一个.rar或是.zip什么的,然后把后缀名改成极其奇怪的名字,比如.jpsb什么的(不知道的同学们还以为这是那种类型的新型文件)。然后在安装的时候可以偷偷地把文件解压到系统临时目录里面,然后在复制过来。。。反正怎么好玩怎么整就行了~
这几天去研究一下比较牛X的插件技术是怎么实现的,也顺便鄙视一下自己~