构建插件式的应用程序框架

上传人:wt****50 文档编号:44572907 上传时间:2018-06-14 格式:PDF 页数:21 大小:358.01KB
返回 下载 相关 举报
构建插件式的应用程序框架_第1页
第1页 / 共21页
构建插件式的应用程序框架_第2页
第2页 / 共21页
构建插件式的应用程序框架_第3页
第3页 / 共21页
构建插件式的应用程序框架_第4页
第4页 / 共21页
构建插件式的应用程序框架_第5页
第5页 / 共21页
点击查看更多>>
资源描述

《构建插件式的应用程序框架》由会员分享,可在线阅读,更多相关《构建插件式的应用程序框架(21页珍藏版)》请在金锄头文库上搜索。

1、1 开篇开篇 说起插件(plugin)式的应用程序大家应该不陌生吧,记得很早以前有一款很流行的MP3 播放软件 winmap,它是我记忆里最早认识的一款使用插件模式的应用程序,你可以使用他的插件管理器插入很多的音乐效果器,皮肤,甚至是歌词显示的面板。接下来看到了Photoshop 使用插件模式管理虑镜。最后发现只要是大一点的应用程序基本都使用了插件式的程序框架,就拿我们最常用的工具来说吧,Visual Studio、Office、Delphi、Eclipse 等等。Eclipse 将插件模式发挥到了及至,因为他是开源的,所以众多的爱好者,开发出了让人应接不暇的插件。i 为什么使用插件式的应用程

2、序框架呢?我的答案就是他为应用程序的功能扩展提供的无限的想象空间。 一个应用程序, 无论你前期做了多少的市场调查, 需求分析做的多么完美,你也只是迎合一部分人的期望,更甚,你只迎合了一部分人的一部分期望,或者一部分人在某一时间的一部分期望。 所以当程序发布以后, 你依然有机会提供新的功能而不必重新发布程序, 人们也可以根据自己的需要来开发新的功能来满足自己的需求, 据我所知有很多的软件公司就是专门开发插件来赚钱,真是一举多得,何乐而不为呢? 我们来看一些常见的提供插件模式的应用程序是如何实现插件功能的。 据我的使用经验来看,Visual Studio 和 Office 其实都是自动化程序,通过

3、 COM 的方式提供了一组接口。开发人员可以利用这些接口来开发基于 COM 的插件,当插件开发完成后,注册 COM 组件。在Visual Studio 中你可以使用 Addin 管理器来选择是否启用插件,而 Office 似乎省去了这一步,一旦你注册了 Office 插件,Office 应用程序在启动的时候会自动加载插件。COM 方式似乎最受微软的宠爱,因为 COM 是一种二进制重用标准,用户可以使用大部分流行的语言来开发插件。当然你也可以使用别的方式,比如普通 DLL,只是这样对于开发人员来说适用面就窄了,因为各个厂商 DLL 的内部结构是不尽相同的,比 VC 开发出的 DLL 和 Borl

4、and Cbuilder 开发出的 DLL 结构就不同,需要专门的工具进行转换。现在,还有另外一种方式,使用 dotNet 的 Assembly, 使用 dotNet 的好处是开发简单, 使用也同样简单 (不需要注册) ,而且你也可用通过 COM 互操作让开发人员可以使用各种语言进行插件开发,当然用 dotNet开发还是最简单的,省去不少中间过程。 其实上面介绍的三种方式开发的插件最终还是寄宿在 DLL 中, 从中我们就可以看出一些端倪。 为什么使用 DLL 呢?DLL 虽然也是 PE 格式, 但是他是不能独立运行的, 一般情况下,都是在运行时加载到应用程序的内存空间。 插件模式正好是利用了这

5、一点, 插件不是应用程序的一部分,他以二进制的方式独立存在,由用户决定是否使用他。 那么插件是如何与应用程序进行交互的呢?首先必须有一个契约, 应用程序要声明我有哪些功能是可以被插件使用的,并且具备什么条件才能成为我的插件。其次,应用程序不依赖于插件,也就是说,没有你插件,我也可以很好的运行。再次,应用程序必须有一种策略来获取插件存在的位置,比如 Visual studio 是通过注册表的方式。最后,应用程序可以通过某种方式动态的加载插件。 2 订立契约订立契约 无论是用 COM 的方式,还是普通 DLL,抑或.NET 方式来实现插件框架,首先要面临的问题就是如何订立契约。 如同我上一篇文章讲

6、到的一样, 契约是应用程序和插件之间进行交互的依据和凭证。 应用程序必须声明我有什么样的功能可被插件使用, 并且插件必须符合什么条件才能被我使用。反之,插件必须要知道应用程序提供什么样的功能,我才能将自己的功能融入到应用程序的体系中。本系列文章主要讲如何使用.NET 实现插件式的应用程序框架,所以其它的方式我就不再提了。 如何使用.NET 订立契约呢?首先想到的 Interface, 其次是抽象类, 但是在插件模式中使用接口, 因为我们是在满足应用程序的主要目的的基础上来提供附加的插件功能, 就这一点来说, 接口更灵活, 更容易扩展。 接下来, 如何订立契约的内容呢?这就要根据业务需求了,为了

7、讲解的方便,我们定义一个最最基本的插件式应用程序的插件契约。我们做一个假定,我们的应用程序是一个多文档的应用程序,包含一个主菜单栏,一个工具栏,菜单栏可以在程序的上下左右四个方向停靠,另外还有一个状态栏。到后边,如果有必要,我会扩展这个应用程序,让他本身提供更多的可供插件使用的功能。所以就目前而言,我想实现的功能就是让插件为主程序添加工具条、菜单项并实现一些简单的功能。 应用程序向插件提供服务有两种方式: 1) 一种是直接在应用程序接口中声明属性或者方法 2) 一种是将应用程序接口声明成一个服务容器 我打算两种方式都用, 明确的功能就在接口中直接声明成属性或者方法, 另外将应用程序声明成一个服

8、务容器,以方便插入更多的服务功能,提高应用程序的可扩展性。 下边是一个非常简单的应用程序接口定义,对于我们的假定已经足够了。 using System.ComponentModel.Design; using System.Windows.Forms; namespace PluginFramework public interface IApplication : IServiceContainer ToolStripPanel LeftToolPanel get; ToolStripPanel RightToolPanel get; ToolStripPanel TopToolPanel

9、get; ToolStripPanel BottomToolPanel get; MenuStrip MainMenuStrip get; StatusStrip StatusBar get; 插件的接口定义: using System; namespace PluginFramework public interface IPlugin IApplication Application get; set; String Name get; set; String Description get; set; void Load(); void UnLoad(); event EventHand

10、ler Loading; 3 动态加载动态加载 不管你采用什么方式实现插件式的应用程序框架,核心还是动态加载,换句话说,没有动态加载技术也就无所谓插件式的应用程序框架了。使用 COM 实现的话,你可以利用 COM的 API 通过 ProgID 来动态创建 COM 对象,如果使用普通 DLL,你需要使用 Windows 的 API函数 LoadLibrary 来动态加载 DLL,并用 GetProcAddress 函数来获取函数的地址。而使用.NET技术的话,你需要使用 Assembly 类的几个静态的 Load(Load,LoadFile,LoadFrom)方法来动态加载汇集。 一个 Asse

11、mbly 里可以包含多个类型, 由此可知, 一个Assembly 里也可以包含多个插件,就像前一篇文章所讲,只要它从 IPlugin 接口派生出来的类型,我们就承认它是一个插件类型。那么 Assembly 被动态加载了以后,我们如何获取 Assembly 里包含的插件实例呢?这就要用到反射(Reflection)机制了。我们需要使用 Assembly 的 GetTypes 静态方法来得到Assembly 里所包含的所有的类型,然后遍历所有的类型并判断每一个类型是不是从 IPlugin接口派生出来的,如果是,我们就使用 Activator 的静态方法 CreateInstance 方法来获得这个

12、插件的实例。.NET 的动态加载就是这几个步骤。下来,我做一个简单的例子来演练一下动态加载。首先声明一点,这个例子非常简单,纯粹是为了演练动态加载,我们的真正的插件式的应用程序框架里会有专门的 PluginService 来负责插件的加载,卸载。 我们的插件位于一个 DLL 里,所以我们首先创建一个 Class library 工程。创建一个FirstPlugin 类让它派生于 IPlugin 接口,并实现接口的方法和属性,由于本文的目的是演示动态加载,所以 IPlugin 接口的 Loading 事件我们就不提供默认的实现了,虽然编译的时候会给出一个警告, 我们不必理会它。 这个插件的功能就

13、是在应用程序里创建一个停靠在主窗体底部的 ToolStrip,这个 ToolStrip 上有一个按钮,点击这个按钮,会弹出一个 MessageBox 显示“The first plugin” 。下面是代码: using System; using System.Windows.Forms; using PluginFramework; namespace FirstPlugin public class FirstPlugin : IPlugin private IApplication application = null; private String name = “; private

14、String description = “; #region IPlugin Members public IApplication Application get return application; set application = value; public string Name get return name; set name = value; public string Description get return description; set description = value; public void Load() if (application != null

15、 ToolStripButton button = new ToolStripButton(“Click Me“); button.Click += new EventHandler(button_Click); sampleToolStrip.Items.Add(button); /在主程序的底端添加ToolStrip application.BottomToolPanel.Controls.Add(sampleToolStrip); void button_Click(object sender, EventArgs e) MessageBox.Show(“The first plugin

16、“); /相关的文章主要讲动态加载,所以卸载就不实现了 public void UnLoad() throw new Exception(“The method or operation is not implemented.“); public event EventHandler Loading; #endregion 接下来我们创建一个 Windows Application 工程让主窗体派生于 IApplication 接口并实现IApplication 接口的方法和属性,下来我们声明 1 个 MenuStrip 和 1 个 StatusStrip,让他们分别停靠在窗口的顶部和底端,接下来我们声明 4 个 ToolStripPanel,分别人他们停靠在上下左右四个边,最后我们创建一个 ToolStrip,在上边添加一个

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号