前言
之前,想到这样一个情景,用一个脚本来描述一个服务的操作,这样做的好处是,业务逻辑落到了配置文件。业务变化时只需通过修改配置,而不需要重新编译系统。
最近几天,由于工作需要,转到了服务器的研发,刚好碰上这一应用场合,终于有机会完成这一脚本的设计。
IOS简介
IOS是In/Out Script(输入/输出脚本)的简称,在我的设计中,用in,out,script3个节点来描述一个服务调用。
设计目标
采用XML作为服务的描述语言,因为目前XML解析的库已非常完善,采用XML能够省去大量的语法解析工作;
一个服务对外界的元素是输入参数和输出参数,所以定义了In,Out两个节点分别描述;
一个服务应该包含多个操作,这些操作有先后关系,赋值关系;
服务的多个操作应该支持顺序,分支,循环3个基本的执行方式;
服务执行过程中会产生临时变量,要支持临时变量的存放;
必须保证服务的多个操作的事务性;
服务的内部错误处理。
服务脚本节点定义
set节点
定义输入/输出参数:name参数名称
io节点
定义Invoke/Out操作:i执行脚本,o输出变量
if/elseif/else节点
定义条件执行节点:i执行判断脚本
foreach节点
定义循环遍历执行节点:i获取父项脚本,o输出子项变量
throwerror节点
定义引发异常节点:i获取异常信息脚本
error节点
定义错误处理节点
完整的服务脚本
<service name="">------【服务节点】name:服务名称
<in>------【输入参数】
<set name=""/>
</in>
<out>------【输出参数】
<set name=""/>
</out>
<script t="false">------【服务脚本】t:transaction事务控制
<io i="" o=""/>
<io i="" o=""/>
<if i="">
<io i="" o=""/>------if结果为true时执行
<io i="" o=""/>
<elseif i="">
<io i="" o=""/>------elseif结果为true时执行
<io i="" o=""/>
</elseif>
<else>
<io i="" o=""/>------if/elseif所有结果为false时执行
<io i="" o=""/>
</else>
</if>
<foreach i="" o="">
<io i="" o=""/>------i值必须是可遍历的数据类型,o值是遍历时的子项
<io i="" o=""/>
</foreach>
<throwerror i=""/>------引发异常能控制事务回滚
<error>
<io i="" o=""/>
<io i="" o=""/>
</error>
</script>
</service>
服务脚本引擎
用来解析执行服务脚本,是服务器的一个子模块。
服务脚本例子
例子1:创建实体对象服务
<service name="NewEntity">
<in>
<set name="Type"/>
</in>
<out>
<set name="New"/>
</out>
<script t="true">
<io i="CreateEntity(@Type)" o="New"/>
<io i="CreateDTS()" o="New.DTS"/>
<io i="InsertEntity(@New)" o="P1"/>
<if i="!@P1">
<io i="Null()" o="New"/>
</if>
<error>
<io i="Error()" o="New"/>
</error>
</script>
</service>
例子2:带文件操作和数据库操作,并且有事务控制的例子
<service name="CreateSheet">
<in>
<set name="Template" type="string"/>
<set name="Items" type="manifest"/>
</in>
<out>
<set name="DTS"/>
<set name="Error"/>
</out>
<script t="true">
<!--创建文件映射?-->
<io i="CreateEntity('EBM.Data.File')" o="File"/>
<io i="CreateDTS()" o="File.DTS"/>
<io i="FormatDate(Date(),'yyyyMMdd')" o="File.Folder"/>
<io i="@File.DTS" o="File.Name"/>
<io i="'.fxl'" o="File.Ext"/>
<io i="GetDriver()" o="File.Driver"/>
<io i="ToFullPath(Concat(@File.Folder,'/',@File.Name,@File.Ext), @File.Driver)" o="SavePath"/>
<!--创建文件-->
<io i="ToFullPath(@Template)" o="Path"/>
<io i="LoadSheet(@Path)" o="Sheet"/>
<io i="FillSheet(@Sheet, @Items)" o="Sheet"/>
<io i="InvokeSheet(@Sheet)" o="Sheet"/>
<!--写文件-->
<io i="WriteText(@SavePath, @Sheet)" o="Success"/>
<!--入库-->
<io i="InsertEntity(@File)" o="Success"/>
<if i="!@Success">
<throwerror i="'错䨪误¨®:êoInsertEntity(@File)'"/>
</if>
<!--
<throwerror i="'事务回滚测试'"/>
-->
<io i="@File.DTS" o="DTS"/>
<error>
<io i="" o="DTS"/>
<io i="Error()" o="Error"/>
</error>
</script>
</service>
相关文章

被折叠的 条评论
为什么被折叠?



