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下的实现类的命名错误或者是实现类内部语法错误。