1、QPlugins 是什么?
QPlugins 是一个插件管理引擎,它基于 Delphi 编写,支持各种语言做为宿主和插件。虽然是一个插件引擎,但 QPlugins 更想强调的是服务的概念,而不是插件。插件在 QPlugins 里只是各种服务的容器,各种服务才是 QPlugins 想要整合的主体。QPlugins 的详细介绍请参考 QPlugins 专题的其它说明。
2、服务名有什么限制吗?允许重名吗?
几乎没有,你可以用你键盘能够输入的任何字符(开始转折)除了保留用于路径分割符的 “/”。至于重名,允许,当然允许。这世界上这么多人,名字重的海了去了,QPlugins 也允许重名,包括 ID 也可以重。如果没有路由器拦截,ByPath / ById 会返回第一个找到的实例做为结果,有了路由器,就由路由器规则负责控制了。
3、我自己写的服务必需注册到 Services 分支下面吗?
强扭的瓜不甜,郎情妾意才是完美的结局。所以,QPlugins 不会限制你注册服务到那里,你可以注册到 QPlugins 的任何分支下面,甚至可以添加一个新的分支。不过,QPlugins 只是一个傻傻的痴程序,所以,调用它的 Start 和 Stop 时,只会在 Loaders 下面找实现了 IQLoader 接口的服务,而 ByPath 时,只会在 Routers 分支下找路由器。如果你不调用它的接口来处理,当然可以随意,比如你将加载器全放到 /MyLoaders 分支下面,然后自己遍历每个 Loaders 并加载它,在程序退出前再挨个卸载它。
这里强调下,QPlugins 约定的 Loaders / Routers /Services 只是一个建议的根结点,并不代表你没有自由。
4、支持单实例和多实例吗?
QPlugins 体系里,服务编写者决定提供的是单实例还是多实例。如果提供的是单实例(默认),不需要做任何额外的操作,如果要提供多实现,则需要重载 GetInstance 方法返回新实例。由此这里就有了一个问题:
- a. 如果服务类型是一致的,并且是单实例的,那么我们只需要简单的返回自身就好了(实际上TQService的默认 GetInstance 实现就是这样子干的)。
- 如果服务类型是一致的,但要求是多实例的,那么我们返回一个新建的当前类型的实例就好了。
- 如果服务类型是不致的,实际是由另一个服务提供,那么 GetInstance 返回新的服务就好了。这个实例实际上就是在使用时才创建的,如果你愿意,可以自建缓冲池,从池中取,这就是题外话了。
5、QPlugins 是否支持工厂模式?
工厂模式实际上个人感觉也是蛮有争议的一个东西,工厂模式隐藏了类的细节,从而只能在一定的抽象层次上来考虑问题。凡事就是两面,毁誉可参半。QPlugins 内核不试图去区分这些东西,在请求服务时,QPlugins 可以:
- 通过 ByPath 来请求服务;
- 通过 ById 来请求服务;
- 通过 as 操作符来请求服务(包括 QueryInterface、Supports等);
工厂模式实际上对应的是 ByPath 方式
PluginsManager.RequireService('Services/Human')
上面会请求一个 Services/Human 服务,而如果有路由器( Routers ) 支持,则可以加入一些额外的参数和筛选操作,如:
PluginsManager.RequireService('Services/Human?type=woman')
接下来是一个好消息,一个坏消息。好消息是 QPlugins 本身支持路由器的代码已经实现,坏消息是路由器的实现代码目前还没有写,需要等待它完成。
6、其它的问题?
你想到了再问,不问我也不知道。程序如果有 Bug 就直接报告 Bug,没 Bug 就争取用出 Bug~~~~