代码改变世界

基于插件架构的简单的Winform框架(上)

2012-05-20 16:59  ps_zw  阅读(2201)  评论(1编辑  收藏  举报

一、概述

  在前面的文章中系统的介绍过MEF技术,我们知道通过MEF可以很容易的实现应用程序的扩展。那么除了MEF之外应该还有很多技术可以实现应用程序的扩展(毕竟MEF是随着.net4.0一起发布的)。本文就简单的介绍下其中一种扩展技术:【插件架构】,分为上、下两篇,上篇介绍基本概念,下篇为应用篇。由于插件架构在winform中应用较为广泛,因此本文的写作目的是使用插件架构搭建一个简单的winform程序。

二、插件与插件架构(或者叫“插件机制”)

1.插件

      日常,我们使用各种软件(特别是使用VS)时,可以安装很多的插件。那插件(plug-in)是什么呢?先介绍一个概念:宿主(host),顾名思义就是程序寄宿或挂载对象。有了宿主我们就可以定义插件了:符合指定宿主某种接口,并能够提供特定功能的程序。(个人观点)

2.插件架构

   一时也没有想到什么好的语句来定义插件架构,但是可以这样描述它:插件架构是这样一种的设计,它降低了宿主与具体的应用模块的依赖,对于宿主来说,它不再关心每一个具体的插件如何实现,只要该插件满足宿主的规范,那么宿主就能够加载它。 相反,作为插件,它只要满足了宿主的规范便可被宿主加载。这样设计出来的程序具有很强的扩展性。

使用插件架构时一般都会使用到反射(reflector)。

三、示例

在上面的描述中我们提到了插件需要满足宿主的某种规范。这种规范在实际编码中便体现成Interface或者abstract class。

1.我们定义一个接口如下: 

1     /// <summary>
2     /// 插件应遵循的接口
3     /// </summary>
4     public interface IPlugIn
5     {
6         void Show();
7     }

 

2.定义一个插件,需要实现上述接口:

 1     /// <summary>
 2     /// 具体插件
 3     /// </summary>
 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         #endregion
16     }


3.重点来了,我们这里定义一个宿主,并利用反射创建具体插件的实例:

 1    public class PlugInHost
 2     {
 3         /// <summary>
 4         /// 加载所有的插件
 5         /// </summary>
 6         /// <returns></returns>
 7         public List<IPlugIn> LoadPlugIns()
 8         {
 9             List<IPlugIn> plugList = new List<IPlugIn>();
10             Assembly pluginAssembly = null;
11             string path = System.IO.Directory.GetCurrentDirectory() + "/plugins/MyPlugin.dll";
12             try
13             {
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     }

 

看下运行结果:

image

到此我们制作了一个简单的基于插件架构的程序,我可以看一下项目结构:

image

在上述解决方案中,引用关系为:Host引用AppContex,MyPlugIn引用AppContex。这样就把Host和具体PlugIn隔离开了,减少了依赖,方便我们队应用程序的扩展。

      当然实际应用中的插件架构要比上面这个例子复杂很多。其中还要涉及到插件和宿主的交互,插件之间的交互。在下一篇文章中,我们将具体介绍插件架构在Winform程序中的应用,将涉及到插件同宿主、插件同插件之间的交互,