欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

程序员文章站 2022-04-15 15:12:23
前言:引擎组件的基本职责是负责流程流转,但是在流转过程中,除了对内部控制逻辑进行实现外,也不可避免的要去调用或者响应外部事件。本文主要描述外部事件的类型,以及调用方法过程。 1. 外部事件的类型 外部事件的类型是随着引擎功能的需要而不断增加,开发人员也可以在此基础上进行扩展,目前主要常用的事件类型如 ......

前言:引擎组件的基本职责是负责流程流转,但是在流转过程中,除了对内部控制逻辑进行实现外,也不可避免的要去调用或者响应外部事件。本文主要描述外部事件的类型,以及调用方法过程。

1. 外部事件的类型

    外部事件的类型是随着引擎功能的需要而不断增加,开发人员也可以在此基础上进行扩展,目前主要常用的事件类型如下:

public enum actionmethodtype
{
  localmethod, //本地程序
  webapi,  //调用webapi程序
  sql,    //执行sql脚本
  storeprocedure,    //调用存储过程
  python,     //执行python脚本
}

2. 外部事件的调用方法

2.1 本地程序

    要调用的外部服务类,需要首先继承externalservicebase类,同时实现iexternalservice接口。下面的ordersubmitservice类就是一个具体实现类。请参考slickflow.module.external项目。

/// <summary>
    /// 订单提交服务类(对应订单流程中订单提交节点)
    /// </summary>
    public class ordersubmitservice : externalservicebase, iexternalservice
    {
        /// <summary>
        /// 业务逻辑前置调用方法
        /// </summary>
        public override void execute()
        {
            //实现用户自己的业务逻辑
            var id = delegateservice.getid();
            var amount = delegateservice.getvariable("amount");
             dosomethingelse(amount, 20);
        }
 
        /// <summary>
        /// 业务逻辑具体实现方法
        /// </summary>
        /// <param name="amount"></param>
        /// <param name="newamount"></param>
        private void dosomethingelse(string amount, int newamount)
        {
            var intamount = 0;
            int.tryparse(amount, out intamount);
 
            if (intamount < newamount)
            {
                delegateservice.setvariable("amount", newamount.tostring());
            }
 
            //调用其它业务处理逻辑
            var session = delegateservice.getsession();
             //实现其它数据库业务逻辑
            //.............................
        }
}

    在引擎流转执行过程中,当解析到节点上有调用外部事件的action定义时,将会使用反射方法,查找到组件是否有ordersubmitservice类,并且是实现了extneralservicebase和iexternalservice 接口的服务类,才能被执行其中的execute()方法,必须满足上述的查找基类继承和接口实现条件才能被反射执行,否则是不能被执行的。这样可以确保是执行到了明确定义的事件程序代码。

2.2 webapi

 步骤1:节点属性上的事件定义

Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

 

 步骤2:流程变量定义

    通过workflowservice接口写入流程变量(wfprocessvariable),变量用来传递webapi方法的参数,此处作为示例:

Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

  步骤3:被调用webapi程序的接口方法实现示例

    上述示例中有两个参数:runner和role, 在webapi的方法代码中,可以使用json格式数据作为接收,然后根据做序列化处理。

Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

2.3 sql

    在节点绑定事件中,可以执行sql语句,sql语句的文本和参数可以通过节点属性来定义,如下图所示:

Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

      流程变量的参数列表:

Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

  2.4 storeprocedure

    存储过程是数据库定义的包含sql脚本语法的程序过程(比如把上述的sql脚本单独保存为存储过程),默认限定在同一个数据库实例中,支持入口参数,定义时,指定参数名称还有存储过程的名称就可以。

 Slickflow.NET 开源工作流引擎高级开发(五) -- 引擎和外部事件的交互

2.5 python

     python脚本调用通sql脚本调用,需要复制python脚本,然后申明参数列表。需要主要的是目前仅支持ironpython版本。

3. 总结:

    在跟外部事件交互调用过程中,调用逻辑统一封装在actionexecutor.cs文件中,代码实现并没有特别复杂,主要是统一做了参数的存储和调用的处理,其中参数存在wfprocessvariable表中,然后在事件调用过程中,使用delegateservice方法来读取参数列表,从而完成最终方法的调用。

    客户方如果对一些代码的实现有特殊的要求,客户方开发人员可以在此基础上完成二次开发或者定制,其基本要求是明白以下三个要素:节点属性定义读取、流程变量的存储和读取以及动态方法的调用。