QPlugins 会实现一个微内核,但微内核并不意味着功能的削弱,反而因为微内核,从而使整个插件引擎更具有灵活性和可塑性。
微内核负责什么?
- 目录
这个目录是插件提供的服务的目录,它是面向服务的优化的。为啥不是面向插件优化,这是因为我们在程序设计时,更关心的是能不能提供某项服务,而不是要关心那个插件提供了这项服务,因此,在设计时就要考虑面向服务优化。 - 接口
QPlugins 使用接口来提供各种各样的功能。只所以使用接口,是因为它良好的跨语言、跨平台、自维护的特性。QPlugins 提供一个返回全局的 IQPluginsManager 接口的函数 PluginsManager,它是一切服务的入口。程序如果要请求某项服务,那么接口会很简单:
1、基于 QueryInterface 的方法
假设我们查询某项名为 IMyService 接口的服务,基于 QueryInterface 我们有几个办法:var AIntf:IMyService begin if PluginsManager.QueryInterface(IMyService,AIntf)=S_OK then ... end;
或
var AIntf:IMyService begin AIntf:=PluginsManager as IMyService; if Assigned(AIntf) then ... end;
或
var AIntf:IMyService begin if Supports(PluginsManagerIMyService,AIntf) then ... end;
2、基于类工厂的方式
var AIntf:IMyService begin AIntf:=PluginsManager.ByPath('Services/MyService') as IMyService; ... end;
- 服务
IQPluginsManager 内核内部只维护三个服务列表:
1、加载器( Loader )列表
加载器负责加载特定格式的插件,这个插件具体提供什么服务,以什么接口提供服务都是由加载器负责约定和加载的。
2、路由器( Router )列表
路由器负责管理服务查询请求并将服务重定向到特定的服务提供者实例,以最终为用户提供服务。
3、普通服务( Services )列表
非上述两种服务的普通服务,都注册到此目录下,构成一个完整的目录树。如果一个服务由多项服务提供时,由路由策略决定使用那个服务。
在 QPlugins 中,加载器和路由器是两个特殊的服务类别,内部实际上也不再关心其它的服务。加载器和路由器本身也是一个服务,第一个加载器可以加载一个插件,而这个插件提供一个全新的加载器,这样形成支持不同的插件形式的扩展。 - 实例化
插件提供的服务在提供给调用者之前,它需要实例化。这里就牵涉到单根和多根的问题,不过这个问题,不归插件引擎管,而是服务提供者自己在实现服务的 NewInstance 接口时来处理。服务的使用者不会关心我使用的是单根实例还是多根实例,它关心的是你是否能够提供我需要的服务并提供正确的结果。