一、概述
在前面的文章中系统的介绍过MEF技术,我们知道通过MEF可以很容易的实现应用程序的扩展。那么除了MEF之外应该还有很多技术可以实现应用程序的扩展(毕竟MEF是随着.net4.0一起发布的)。本文就简单的介绍下其中一种扩展技术:【插件架构】,分为上、下两篇,上篇介绍基本概念,下篇为应用篇。由于插件架构在winform中应用较为广泛,因此本文的写作目的是使用插件架构搭建一个简单的winform程序。
二、插件与插件架构(或者叫“插件机制”)
1.插件
日常,我们使用各种软件(特别是使用VS)时,可以安装很多的插件。那插件(plug-in)是什么呢?先介绍一个概念:宿主(host),顾名思义就是程序寄宿或挂载对象。有了宿主我们就可以定义插件了:符合指定宿主某种接口,并能够提供特定功能的程序。(个人观点)
2.插件架构
一时也没有想到什么好的语句来定义插件架构,但是可以这样描述它:插件架构是这样一种的设计,它降低了宿主与具体的应用模块的依赖,对于宿主来说,它不再关心每一个具体的插件如何实现,只要该插件满足宿主的规范,那么宿主就能够加载它。 相反,作为插件,它只要满足了宿主的规范便可被宿主加载。这样设计出来的程序具有很强的扩展性。
使用插件架构时一般都会使用到反射(reflector)。
三、示例
在上面的描述中我们提到了插件需要满足宿主的某种规范。这种规范在实际编码中便体现成Interface或者abstract class。
1.我们定义一个接口如下:
1 ///2 /// 插件应遵循的接口3 /// 4 public interface IPlugIn5 {6 void Show();7 }
2.定义一个插件,需要实现上述接口:
1 ///2 /// 具体插件 3 /// 4 public class MyPlugIn : IPlugIn 5 { 6 7 8 #region IPlugIn 成员 9 10 public void Show()11 {12 Console.WriteLine("This is my PlugIn!");13 }14 15 #endregion16 }
1 public class PlugInHost 2 { 3 ///4 /// 加载所有的插件 5 /// 6 ///7 public List LoadPlugIns() 8 { 9 List plugList = new List ();10 Assembly pluginAssembly = null;11 string path = System.IO.Directory.GetCurrentDirectory() + "/plugins/MyPlugin.dll";12 try13 {14 //加载程序集15 pluginAssembly = Assembly.LoadFile(path);16 }17 catch(Exception ex)18 {19 Console.WriteLine(ex.Message);20 return plugList;21 }22 Type[] types = pluginAssembly.GetTypes();23 foreach (Type type in types)24 {25 if (type.GetInterface("IPlugIn") != null)26 {27 //创建插件的实例28 plugList.Add((IPlugIn)Activator.CreateInstance(type));29 }30 }31 return plugList;32 33 }34 }
4.定义完了插件、扩展规则、宿主之后我们来尝试调用:
1 static void Main(string[] args) 2 { 3 PlugInHost host = new PlugInHost(); 4 var plugins = host.LoadPlugIns(); 5 foreach (var plugin in plugins) 6 { 7 plugin.Show(); 8 } 9 10 Console.Read();11 }12 }
看下运行结果:
到此我们制作了一个简单的基于插件架构的程序,我可以看一下项目结构:
在上述解决方案中,引用关系为:Host引用AppContex,MyPlugIn引用AppContex。这样就把Host和具体PlugIn隔离开了,减少了依赖,方便我们队应用程序的扩展。
当然实际应用中的插件架构要比上面这个例子复杂很多。其中还要涉及到插件和宿主的交互,插件之间的交互。在下一篇文章中,我们将具体介绍插件架构在Winform程序中的应用,将涉及到插件同宿主、插件同插件之间的交互,