APP下载

基于服务的插件应用程序框架设计与实现

2014-07-03王阳张俊生

电脑知识与技术 2014年12期
关键词:插件服务

王阳 张俊生

摘要: 插件式应用程序开发以其在软件的分析、设计、开发、维护、更新升级等各个环节的巨大的便利性成为近来十分流行的软件开发技术。该文基于.NET Framework平台设计开发插件应用程序框架,利用程序集实现插件的加载,利用服务注册技术将应用程序框架设计成服务容器,实现插件功能的服务化注册管理,无需实现插件加载与管控所需要的底层技术,极大的简化了插件应用程序的开发及扩展。

关键词:.NET Framework;服务;插件

中图分类号:TP319 文献标识码:A 文章编号:1009-3044(2014)12-2750-03

Design and Implementation of A Service Based Plugin Framework

WANG Yang1, ZHANG Jun-sheng2

(1.caeit,Beijing 100041,China; 2.cetc32,Beijing 200233,China)

Abstract: The plugin application development become a very popular technology for its huge convenience on analysis, design, development, maintenance, updating of software development .This article is based on .NET Framework platform to design and develop of plugin application framework ,the assembly is used to achieve load the plugin ,the service registration technology is used to design application framework into service container to manage the function of plugin as service without implementing the underlying technology of plugin load and control , all this greatly simplifies the development and expansion of plugin applications.

Key words: .NET framework; service; plugin

插件应用程序为程序的扩展提供了无限的想象空间。一个应用程序,无论前期做了多少的市场调查,需求分析做的多么完美,也只是迎合一部分人的期望,程序发布以后,依然需要根据实际情况增加或完善功能模块,采用插件式应用程序可以让这些不可预期变得可控。我们经常使用的Visual Studio,Office,Delphi,Eclipse都使用了插件应用程序框架。

插件应用程序开发可以使用微软COM技术,COM是一种二进制重用标准,提供了一组接口,开发人员可以利用这些接口来开发基于COM的插件,当插件开发完成后,注册COM组件;也可以使用普通的DLL,但存在不同厂商标准不一不通用的问题。以上这两种技术都没有提供一个统一的插件功能的管理,当新开发的插件需要引用已有的插件功能时,只能点对点实现功能调用,软件规模达到一定程度时容易出现逻辑混乱。

本文采用微软的.NET Framework平台实现插件的加载与管控。.NET Framework平台已经实现了插件加载与管控所需要的底层技术,程序开发者可以将精力投入到程序架构与流程的设计当中。该文利用程序集Assembly类实现插件的加载,利用服务注册技术将应用程序框架设计成服务容器,实现插件功能的服务化注册管理,极大的简化了插件应用程序的开发及扩展。

1 关键技术介绍

1.1 程序集

程序集是 .NET Framework 应用程序的构造块,旨在简化应用程序部署并解决在基于组件的应用程序中可能出现的版本控制问题,是构成部署、版本控制、重复使用、激活范围控制和安全权限的基本单元,是为协同工作而生成的类型和资源的集合,这些类型和资源构成了一个逻辑功能单元。程序集向公共语言运行时提供了解类型实现所需要的信息。程序集可以是静态的或动态的。静态程序集可以包括 .NET Framework 类型(接口和类),以及该程序集的资源(位图、JPEG 文件、资源文件等)。静态程序集存储在磁盘上的可迁移可执行 (PE) 文件中,动态程序集直接从内存运行并且在执行前不存储到磁盘上。程序集主要执行以下功能:

1)包含公共语言运行时执行的代码。如果可迁移可执行 (PE) 文件没有相关联的程序集清单,则将不执行该文件中的 Microsoft 中间语言 (MSIL) 代码。

2)程序集形成安全边界。程序集就是在其中请求和授予权限的单元。有关应用于程序集的安全边界的更多信息,请参见 程序集安全注意事项。

3)程序集形成类型边界。每一类型的标识均包括该类型所驻留的程序集的名称。在一个程序集范围内加载的 MyType 类型不同于在其他程序集范围内加载的 MyType 类型。

4)程序集形成引用范围边界。程序集的清单包含用于解析类型和满足资源请求的程序集元数据。它指定在该程序集之外公开的类型和资源。该清单还枚举它所依赖的其他程序集。

5)程序集形成版本边界。程序集是公共语言运行时中最小的可版本化单元,同一程序集中的所有类型和资源均会被版本化为一个单元。程序集的清单描述您为任何依赖项程序集所指定的版本依赖性。有关版本控制的更多信息,请参见 程序集版本控制。endprint

6)程序集形成部署单元。当一个应用程序启动时,只有该应用程序最初调用的程序集必须存在。其他程序集(例如本地化资源和包含实用工具类的程序集)可以按需检索。这就使应用程序在第一次下载时保持精简。有关部署程序集的更多信息,请参见 部署应用程序。

7)程序集是支持并行执行的单元。有关运行多个程序集版本的更多信息,请参见 程序集和并行执行。

程序集的对应实现为Assembly类,使用 Assembly 类可以加载程序集、浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类型的实例。Assembly 类提供了静态方法LoadFile实现基于路径标识的动态加载,可以使用GetName方法返回一个 AssemblyName 对象,该对象提供对程序集显示名称部分的访问;GetCustomAttributes 方法列出应用于程序集的属性;GetFiles 方法提供对程序集清单中文件的访问;GetManifest ResourceNames方法提供程序集清单中资源的名称;GetTypes 方法列出程序集中的所有类型;CreateInstance 方法在程序集中搜索和创建类型的实例。

1.2 服务容器

服务是.NET Framework设计时架构的基础,是提供设计时对象访问某项功能的方法实现。服务容器负责提供、添加和移除服务。服务机制的本质是解耦合,是将类型的设计时功能从类型本身剥离出来。如果把类型的设计时功能也封装到类型里,这样的类型包含了很多只有开发人员才会用到而最终用户根本不需要的功能,使得类型既臃肿又不便于扩展,而将设计时功能剥离出来,这样类型就可以不依赖于特定的设计环境。

服务容器可以包含其它服务容器,从而形成服务容器的树结构。当添加服务时,可以用提升指令来添加,当提升服务时,服务将向上添加到任何服务容器,直至达到服务容器树的顶端,这样就可以提供其它进程使用的全局服务。

服务容器的对应实现为ServiceContainer类,ServiceContainer是.NET提供的IserviceContainer接口的实现,可以使用AddService添加服务,RemoveService移除服务,GetService获得服务。

2 应用程序框架设计与实现

2.1 应用程序框架组成

要实现插件框架与插件的交互,必须有一个插件框架与插件交互的准则,即框架的运行不应依赖于插件,且能够获得插件存在的位置,具备动态加载插件的能力,必须要声明有哪些功能是可以被插件使用的,定义插件被加载的条件。.NET Framework平台下我们可以使用灵活可扩展的接口来实现这个准则。

插件与框架之间的通信可以用服务注册技术实现。将主框架申明为一个根服务容器,将插件对外所能提供的功能视为一个服务,并在接口中申明。插件在被加载的同时,完成插件服务向根服务容器的注册,并由根服务容器进行管理,对其它插件提供查询服务。

基于以上的设计思路,一个基于服务的插件式应用程序框架应由3个基本部分组成,如图1所示。主框架负责插件与服务的管理,插件的管理主要负责插件的加卸载,服务管理主要负责插件服务的注册、查询;接口定义主要由插件加载接口与服务接口组成,插件加载接口定义了要实现插件框架与插件的交互必须遵循的准则,每个插件都必须实现这个接口,服务接口由各个插件申明,申明各个插件所能提供的服务;插件由插件加载及插件服务组成,插件加载实现了接口定义中的插件加载接口,负责与主框架的交互,插件服务具体实现了接口定义中申明的服务接口,负责提供实际的插件功能。

2.2 应用程序框架实现

应用程序框架的实现首先从接口开始,接口申明中定义了四种类型的接口,如图2所示。其中IApplication接口继承IServiceContainer,负责服务的注册与删除;IPlugin接口定义了插件与主框架交互时必须实现的方法与属性,由插件实现;IPluginService接口是主框架申明的加载插件服务,主要负责插件的加载与删除;IService接口是所有插件服务接口的基接口,定义了插件服务必须实现的基本服务;IMessageDataShowService接口是插件的申明的提供服务的接口,定义了插件所能提供的服务。

应用程序框架实现的第二步是实现主框架,如图3所示。主框架主要包含两个类,其中MainForm类实现程序的可视化并且实现IApplication接口,作为根服务容器,负责服务的加载、删除与查询;PluginService 是接口IPluginService的实现,负责实际完成插件的注册、加载与删除功能。

最后实现插件,如图4所示。MessageDataShowPlugin类实现IPlugin接口,负责与主框架的交互;MessageDataShowService类实现IMessageDataShowService接口,具体实现了接口中申明能提供的服务。

3 结束语

本文阐述了基于服务的插件式应用框架的基本设计思想,并实现了程序运行所需的基本模块,但要在实际项目中使用框架,还需要读者勤于思考,对框架做必要的补充。可在框架中加入数据流的管理模块,将数据流从服务中独立出来;将主框架的显示模块做成显示服务,以便显示的独立,便利更新升级;可以应用设计模式来组织程序的各个模块等等。

参考文献:

[1] 插件技术的扩展机制[EB/OL].http://www.ibm.com/developerworks/cn/xml/x-wxxm29.html.

[2] service container[EB/OL].http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85 ).aspx.endprint

6)程序集形成部署单元。当一个应用程序启动时,只有该应用程序最初调用的程序集必须存在。其他程序集(例如本地化资源和包含实用工具类的程序集)可以按需检索。这就使应用程序在第一次下载时保持精简。有关部署程序集的更多信息,请参见 部署应用程序。

7)程序集是支持并行执行的单元。有关运行多个程序集版本的更多信息,请参见 程序集和并行执行。

程序集的对应实现为Assembly类,使用 Assembly 类可以加载程序集、浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类型的实例。Assembly 类提供了静态方法LoadFile实现基于路径标识的动态加载,可以使用GetName方法返回一个 AssemblyName 对象,该对象提供对程序集显示名称部分的访问;GetCustomAttributes 方法列出应用于程序集的属性;GetFiles 方法提供对程序集清单中文件的访问;GetManifest ResourceNames方法提供程序集清单中资源的名称;GetTypes 方法列出程序集中的所有类型;CreateInstance 方法在程序集中搜索和创建类型的实例。

1.2 服务容器

服务是.NET Framework设计时架构的基础,是提供设计时对象访问某项功能的方法实现。服务容器负责提供、添加和移除服务。服务机制的本质是解耦合,是将类型的设计时功能从类型本身剥离出来。如果把类型的设计时功能也封装到类型里,这样的类型包含了很多只有开发人员才会用到而最终用户根本不需要的功能,使得类型既臃肿又不便于扩展,而将设计时功能剥离出来,这样类型就可以不依赖于特定的设计环境。

服务容器可以包含其它服务容器,从而形成服务容器的树结构。当添加服务时,可以用提升指令来添加,当提升服务时,服务将向上添加到任何服务容器,直至达到服务容器树的顶端,这样就可以提供其它进程使用的全局服务。

服务容器的对应实现为ServiceContainer类,ServiceContainer是.NET提供的IserviceContainer接口的实现,可以使用AddService添加服务,RemoveService移除服务,GetService获得服务。

2 应用程序框架设计与实现

2.1 应用程序框架组成

要实现插件框架与插件的交互,必须有一个插件框架与插件交互的准则,即框架的运行不应依赖于插件,且能够获得插件存在的位置,具备动态加载插件的能力,必须要声明有哪些功能是可以被插件使用的,定义插件被加载的条件。.NET Framework平台下我们可以使用灵活可扩展的接口来实现这个准则。

插件与框架之间的通信可以用服务注册技术实现。将主框架申明为一个根服务容器,将插件对外所能提供的功能视为一个服务,并在接口中申明。插件在被加载的同时,完成插件服务向根服务容器的注册,并由根服务容器进行管理,对其它插件提供查询服务。

基于以上的设计思路,一个基于服务的插件式应用程序框架应由3个基本部分组成,如图1所示。主框架负责插件与服务的管理,插件的管理主要负责插件的加卸载,服务管理主要负责插件服务的注册、查询;接口定义主要由插件加载接口与服务接口组成,插件加载接口定义了要实现插件框架与插件的交互必须遵循的准则,每个插件都必须实现这个接口,服务接口由各个插件申明,申明各个插件所能提供的服务;插件由插件加载及插件服务组成,插件加载实现了接口定义中的插件加载接口,负责与主框架的交互,插件服务具体实现了接口定义中申明的服务接口,负责提供实际的插件功能。

2.2 应用程序框架实现

应用程序框架的实现首先从接口开始,接口申明中定义了四种类型的接口,如图2所示。其中IApplication接口继承IServiceContainer,负责服务的注册与删除;IPlugin接口定义了插件与主框架交互时必须实现的方法与属性,由插件实现;IPluginService接口是主框架申明的加载插件服务,主要负责插件的加载与删除;IService接口是所有插件服务接口的基接口,定义了插件服务必须实现的基本服务;IMessageDataShowService接口是插件的申明的提供服务的接口,定义了插件所能提供的服务。

应用程序框架实现的第二步是实现主框架,如图3所示。主框架主要包含两个类,其中MainForm类实现程序的可视化并且实现IApplication接口,作为根服务容器,负责服务的加载、删除与查询;PluginService 是接口IPluginService的实现,负责实际完成插件的注册、加载与删除功能。

最后实现插件,如图4所示。MessageDataShowPlugin类实现IPlugin接口,负责与主框架的交互;MessageDataShowService类实现IMessageDataShowService接口,具体实现了接口中申明能提供的服务。

3 结束语

本文阐述了基于服务的插件式应用框架的基本设计思想,并实现了程序运行所需的基本模块,但要在实际项目中使用框架,还需要读者勤于思考,对框架做必要的补充。可在框架中加入数据流的管理模块,将数据流从服务中独立出来;将主框架的显示模块做成显示服务,以便显示的独立,便利更新升级;可以应用设计模式来组织程序的各个模块等等。

参考文献:

[1] 插件技术的扩展机制[EB/OL].http://www.ibm.com/developerworks/cn/xml/x-wxxm29.html.

[2] service container[EB/OL].http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85 ).aspx.endprint

6)程序集形成部署单元。当一个应用程序启动时,只有该应用程序最初调用的程序集必须存在。其他程序集(例如本地化资源和包含实用工具类的程序集)可以按需检索。这就使应用程序在第一次下载时保持精简。有关部署程序集的更多信息,请参见 部署应用程序。

7)程序集是支持并行执行的单元。有关运行多个程序集版本的更多信息,请参见 程序集和并行执行。

程序集的对应实现为Assembly类,使用 Assembly 类可以加载程序集、浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类型的实例。Assembly 类提供了静态方法LoadFile实现基于路径标识的动态加载,可以使用GetName方法返回一个 AssemblyName 对象,该对象提供对程序集显示名称部分的访问;GetCustomAttributes 方法列出应用于程序集的属性;GetFiles 方法提供对程序集清单中文件的访问;GetManifest ResourceNames方法提供程序集清单中资源的名称;GetTypes 方法列出程序集中的所有类型;CreateInstance 方法在程序集中搜索和创建类型的实例。

1.2 服务容器

服务是.NET Framework设计时架构的基础,是提供设计时对象访问某项功能的方法实现。服务容器负责提供、添加和移除服务。服务机制的本质是解耦合,是将类型的设计时功能从类型本身剥离出来。如果把类型的设计时功能也封装到类型里,这样的类型包含了很多只有开发人员才会用到而最终用户根本不需要的功能,使得类型既臃肿又不便于扩展,而将设计时功能剥离出来,这样类型就可以不依赖于特定的设计环境。

服务容器可以包含其它服务容器,从而形成服务容器的树结构。当添加服务时,可以用提升指令来添加,当提升服务时,服务将向上添加到任何服务容器,直至达到服务容器树的顶端,这样就可以提供其它进程使用的全局服务。

服务容器的对应实现为ServiceContainer类,ServiceContainer是.NET提供的IserviceContainer接口的实现,可以使用AddService添加服务,RemoveService移除服务,GetService获得服务。

2 应用程序框架设计与实现

2.1 应用程序框架组成

要实现插件框架与插件的交互,必须有一个插件框架与插件交互的准则,即框架的运行不应依赖于插件,且能够获得插件存在的位置,具备动态加载插件的能力,必须要声明有哪些功能是可以被插件使用的,定义插件被加载的条件。.NET Framework平台下我们可以使用灵活可扩展的接口来实现这个准则。

插件与框架之间的通信可以用服务注册技术实现。将主框架申明为一个根服务容器,将插件对外所能提供的功能视为一个服务,并在接口中申明。插件在被加载的同时,完成插件服务向根服务容器的注册,并由根服务容器进行管理,对其它插件提供查询服务。

基于以上的设计思路,一个基于服务的插件式应用程序框架应由3个基本部分组成,如图1所示。主框架负责插件与服务的管理,插件的管理主要负责插件的加卸载,服务管理主要负责插件服务的注册、查询;接口定义主要由插件加载接口与服务接口组成,插件加载接口定义了要实现插件框架与插件的交互必须遵循的准则,每个插件都必须实现这个接口,服务接口由各个插件申明,申明各个插件所能提供的服务;插件由插件加载及插件服务组成,插件加载实现了接口定义中的插件加载接口,负责与主框架的交互,插件服务具体实现了接口定义中申明的服务接口,负责提供实际的插件功能。

2.2 应用程序框架实现

应用程序框架的实现首先从接口开始,接口申明中定义了四种类型的接口,如图2所示。其中IApplication接口继承IServiceContainer,负责服务的注册与删除;IPlugin接口定义了插件与主框架交互时必须实现的方法与属性,由插件实现;IPluginService接口是主框架申明的加载插件服务,主要负责插件的加载与删除;IService接口是所有插件服务接口的基接口,定义了插件服务必须实现的基本服务;IMessageDataShowService接口是插件的申明的提供服务的接口,定义了插件所能提供的服务。

应用程序框架实现的第二步是实现主框架,如图3所示。主框架主要包含两个类,其中MainForm类实现程序的可视化并且实现IApplication接口,作为根服务容器,负责服务的加载、删除与查询;PluginService 是接口IPluginService的实现,负责实际完成插件的注册、加载与删除功能。

最后实现插件,如图4所示。MessageDataShowPlugin类实现IPlugin接口,负责与主框架的交互;MessageDataShowService类实现IMessageDataShowService接口,具体实现了接口中申明能提供的服务。

3 结束语

本文阐述了基于服务的插件式应用框架的基本设计思想,并实现了程序运行所需的基本模块,但要在实际项目中使用框架,还需要读者勤于思考,对框架做必要的补充。可在框架中加入数据流的管理模块,将数据流从服务中独立出来;将主框架的显示模块做成显示服务,以便显示的独立,便利更新升级;可以应用设计模式来组织程序的各个模块等等。

参考文献:

[1] 插件技术的扩展机制[EB/OL].http://www.ibm.com/developerworks/cn/xml/x-wxxm29.html.

[2] service container[EB/OL].http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85 ).aspx.endprint

猜你喜欢

插件服务
自编插件完善App Inventor与乐高机器人通信
服务在身边 健康每一天
服务在身边 健康每一天
服务在身边 健康每一天
MapWindowGIS插件机制及应用
基于Revit MEP的插件制作探讨