service机制
service机制是扩展机制, 通过'Service机制', 保证App之间可以扩展功能,界面,操作,和流程等, 而不必担心原有应用升级带来的问题。
在进入详细讲解前, 先来看三个概念
- service
service即服务, 在系统中service体现为service类.
- service box存放具备同样功能, 特性的一组service, 他们具备同样的接口(interface). 例如: 支付宝, 块钱等支付方式, 同属于一个service box. 通过service_box_id作为唯一标识, 标识每个service box.
- service boxes提供存储所有service box, 及注册到service box的所有service. Service boxes有系统框架base app提供.
service机制中的两个角色
- 这两个角色, 可以同时由一个app来提供供给, 当然也可以由不同app来提供供给
- 供给者和消费者, 并无严格意义上的先后顺序, 可以先有供给者, 也可以先有消费者
provider - 供给者
由供给者提供可用的service
系统底层是通过两个步骤完成的
- 创建一个service box到service boxes中
- 注册service到创建好的service box中
service 注册
- service的注册是通过相应的app的service配置文件, services.xml来完成的
- service.xml当所在app被install(安装)或update(更新)时被加载
services.xml
app/$app_id/services.xml
<services> ... <service id="file_storage" interface="base_interface_sotrager" optname="图片存储引擎"> <class orderby=80>base_storage_filesystem</class> </service> <service id="view_compile_helper"> <class>base_view_compiler</class> </service> ... </services>
- services 是根标签
- service 代表一个service box, 可以包含多个service class, 属性含义如下:
- id: service box的唯一标识service_box_id.
- interface: 接口, 代表service box强制要求注册到service box上需要强制继承的接口类
- optname: 选择名称(不常用, 暂不做详细解释)
- opttype: 选择类型(不常用, 暂不做详细解释)
- classservice class, 提供service能力的类
- orderby 运行顺序.规则: 按照orderby升序,input_time载入时间降序排列, 可以指定orderby,不指定默认50,input_time根据加载顺序的.如果没有指定orderby的话,三个service的顺序就反过来.
consumer - 消费者
消费有两种方式
service - 从指定service box中获取优先级最高的service class
通过service_box_id, 从service box中获取一个优先级最高的service class, 进行相关处理. 默认情况下, 后注册者优先级最高.
用法:
kernel::service($service_box_id);
例子: 通过service_box_id:site_index_seo获取提供页面seo的service class
<?php
class site_ctl_default extends site_controller{
...
$obj = kernel::service('site_index_seo');
if(is_object($obj) && method_exists($obj, 'title')){
$title = $obj->title();
}
...
}
servicelist - 从指定service box中获取所有service class
通过service_box_id, 从相应service box中获取所有service class 进行相关处理. 默认情况下, 后注册者优先级最高.
用法:
kernel::servicelist($service_box_id);
例子: 通过service_box_id:view_helper获取所有关于系统smarty的插件, 并注册在系统中
<?php
class base_component_compiler{
...
function __construct(&$controller){
...
foreach(kernel::servicelist('view_helper') as $helper_path=>$helper){
foreach(get_class_methods($helper) as $method){
$this->set_view_helper($method,$helper_path);
}
}
...
}
}
...
查看所有注册过的service class
bryant@forsky /Users/bryant/codes/ecos %> app/base/cmd dev:show services file_storage base_storage_filesystem view_compile_helper base_view_compiler view_helper base_view_helper ...
service开发注意事项
service box前缀命名规则
请用app_id加下划线做为前缀: "{$app_id}_"
service开发中遇到的问题和解决方案(2011-07-12:sun)
- 注册一个service可能出现各种出错形式,那我们就来看一下,具体会有哪些错误信息。
1、页面出不来效果,并且cmd update无法找到service
- 问题所在:services.xml文件命名错误或者是services.xml内的xml标签写错了。
2、cmd update出现安装成功service提示,但是页面无法出现效果。
- 问题所在:services.xml中的service标签后的id参数(service_name)写错了(系统没有这个service)。
3、页面报错“Don't find *'**'”。
- 问题所在:services.xml中的标签<class>class_name</class>中的"class_name"命名出错。
4、页面报错“HTTP_ERROR_***:500”。
- 问题所在:service对应的lib下的实现类的命名错误或者是实现类内部语法错误。