工作流设计器工作流模板定义工具,通过设计器实现在一定业务范围内的流程自定义;
开发人员在使用设计器时,需要进行配置,要了解设计器中集成的基本元素(Activity)的功能、事件的绑定和属性的设置等;
配置文件的格式如下:
<LocalServiceNode>
<LSDLL name ="WF1" value="LocalServiceLib1.dll" desc="市场竞价 LocalService"></LSDLL>
<LSDLL name ="WF2" value="LocalServiceLib2.dll" desc="调度算法 LocalService"></LSDLL>
</LocalServiceNode>
该配置主要是实现LocalService的动态加载,LocalService 是工作流实现业务流程的核心,后面会详细介绍;
项目名称 |
描述 |
<LocalServiceNode></LocalServiceNode> |
LocalService 节点标记 |
<LSDLL></LSDLL> |
LocalService 动态连接库DLL标记节点 |
name |
LocalService 的名称,最好用中文描述 |
Value |
LocalService 动态连接库DLL名称 |
Desc |
LocalService 对应的业务描述 |
完成上面的配置文件后,需要把LocalService文件(dll)放到设计器所在的目录下,启动设计器后,设计器自动完成LocalService 的动态加载
如果新增加一种业务LocalService,就需要在上面的配置文件中增加一条信息:
<LSDLL name ="WF3" value="LocalServiceLib3.dll" desc="新增业务LocalService"></LSDLL>
同时把LocalServiceLib3.dll文件放到设计器所在的目录,重新打开设计器即可;
工作流设计器采用的WF状态机的模式,状态机工作流主要采用的是事件驱动的方式;设计器主程序界面如下:
工作流设计器界面主要分三部分:功能目录与Toolbar功能按钮区、流程图形化设计区、Activity元素与属性设置区;
Activity元素与属性设置列表如下:
Activity元素名称 |
功能描述 |
主要属性设置 |
1、StateActivity |
状态活动 |
Set as Initial State:设置状态开始状态; Set as Completed State:设置状态为完成状态 Name 状态名称(英文字母)
|
2、EventDrivenActivity |
事件驱动活动 |
该活动是状态活动实现事件驱动的主要元素; Name:元素名称(英文字母) |
3、HandleExternalEventActivity |
绑定外部事件活动 |
InterfaceType:需要绑定的接口类型,对应的是LocalService接口对象; EventName:需要绑定的接口事件,是选定接口对象中的接口事件 |
4、CallExternalMethodActivity |
调用外部方法活动 |
InterfaceType:需要绑定的接口类型,对应的是LocalService接口对象; MethodName:要调用的外部方法名;该方法是选定接口对象中定义的方法; |
5、SetStateActivity |
状态转换活动 |
该元素主要指向当前状态的下一状态,是工作流状态流转的出口; TargetStateName:指向下一个状态的状态名称; |
6、StateInitializationActivity |
状态初始化活动 |
该活动主要是在状态开始运行前执行;主要用来处理状态运行前的初始化操作;在该活动中可以绑定其他的活动来实现对外部方法的调用,达到处理实际业务的目的; |
7、StateFinalizationActivity |
状态结束活动 |
该活动和StateInitializationActivity和刚好相反,它是在一个状态转向另一个状态之前执行;其它的处理和上面的类似; |
8、DelayActivity
|
延时活动 |
对状态处理的延时情况的处理; TimeOutDuration:延时时间间隔的设置; |
9、TerminateActivity |
终止活动 |
用来结束一个工作流流程,当工作流非正常结束时将用到该活动; |
在实际的设计中,还包括“剪切”、“拷贝”、“粘贴”和“删除”等编辑操作,还包括流程图的“缩放”、“导航”、“展开”与“合并”等操作;
在工作流流程设计完成后,点击保存,就生成序列化文件(*.XOML),既工作流模板文件;
在工作流模板完成并保存成物理文件后,就可以对页面流信息进行设置,图示如下:
工作流的页面流信息是和状态信息绑定起来的,开始状态和结束状态一般不用绑定页面流信息;URL地址中填写的是页面的相对路径。
URL参数设置完成后,点击确定,生成一个xml 文件,该文件和工作流模型文件同名,但后缀名不同;例如:工作流模型文件是:WFExpenseAccount.xoml,
也面流配置文件就位:WFExpenseAccount.xml;在实际的调用中可以直接进行修改。
也面流文件格式示例如下:
<WFNodeRUL>
<forward StateName="WaitingForCreateState" URL="CreateOrderBillandStartWF.aspx" />
<forward StateName="OpenState" URL="EditOrderBill.aspx" />
<forward StateName="ProcessedState"URL="ProcessOrderBill.aspx" />
<forward StateName="CompletedState" URL="CompletedOrderBill.aspx" />
</WFNodeRUL>
格式文件注解如下:
项目名称 |
描述 |
<WFNodeRUL></WFNodeRUL> |
节点页面流标签 |
<forward/> |
节点标签 |
StateName |
工作流状态名属性 |
URL |
状态对应的页面流地址 |
上面的工作完成后,把保存出来的物理文件(*.xoml、*.xml、*.cs)拷贝到调用项目的BIN目录下,工作流引擎就可以对这些文件进行加载调用。
工作流引擎是工作流调用、执行、流转与监控的基础部分;工作流引擎对WF调用运行机制进行了封装,对外提供统一的调用接口;
LocalService 动态加载参数配置文件格式如下:
<LocalServiceNode>
<LSDLL Name ="WF1" LocalServiceDLL ="WFLocalServicesLib" NameSpaceClass="StateMachineLocalService.StateMachineService" desc=""></LSDLL>
<LSDLL Name ="WF2" LocalServiceDLL ="WFLocalServicesLib2" NameSpaceClass="WFLB.Orderbill" desc="订单类"></LSDLL>
</LocalServiceNode>
格式文件注解如下:
项目名称 |
描述 |
<LocalServiceNode></LocalServiceNode> |
LocalService类型节点 |
<LSDLL></LSDLL> |
LocalService 动态连接库(DLL)节点 |
Name |
动态连接库名称(中文描述) |
LocalServiceDLL |
动态连接库物理文件名称 |
NameSpaceClass |
LocalService命名空间加类名字符串 |
desc |
LocalService 业务功能描述 |
|
|
上述配置文件配置好后,需要把LocalService动态连接库拷贝到项目程序的BIN目录下,引擎就可以对这些LocalService进行动态的加载;
工作流对外提供的调用接口主要封装在WFWebUIService 类中;WFWebUIService类提供主要的功能函数列表如下:
功能函数名称 |
功能与参数描述 |
Public string StartWorkflow(string xomlFileName) |
功能:创建一个新的工作流实例 参数:xomlFileName 工作流模板文件名称 返回值:工作流实例Guid 字符串 |
public string GetWFStateUrl(string xomlFileName, string curStateName) |
功能:获得工作流状态邦定的页面流信息 参数:xomlFileName 工作六流模板文件名称 curStateName 工作流当前状态名 返回值:URL 地址串 |
public string GetWFCurrState(string wfInstanceId) |
功能:获得当前工作流的状态 参数:wfInstanceId 工作流实例ID(必须是GUID,并且该工作流实例必须没有结束) 返回值:当前工作流的状态名 |
public void RaiseEventDriven(DynamicForm form) |
功能:通用事件驱动的调用端口 参数:DynamicForm 自定义参数输入类,主要封装的是HashTable,通过键值对的方式传入参数 返回值:无 |
public DataSet GetRecformExeSQL(string qyrSQL) |
功能:获得数据库记录集 参数:qrySQL 操作数据库的SQL语句 返回值:DataSet 数据集 |
public DataSet GetRecFromExeProcedure(string strStoredProcedureName) |
功能:执行没有不带参数的存储过程,返回数据集 参数:strStoredProcedureName 存储过程名称 返回值:DataSet 数据集 |
public DataSet GetRecFromExeProcedure(string strStoreProcedureName,SqlParameter[] sqlParameter) |
功能:执行带输入参数的存储过程,返回数据集合 参数:StrStoreProcedureName 存储过程名称 sqlParameter 存储过程参数列表 返回值:DataSet 数据集 |
public void InsertOrUpdateFromExeProcedure(string strStoreProcedureName,SqlParameter[] sqlParameter) |
功能:通过执行存储过程进行插入和更新数据库的操作 参数:sqlParameter 存储过程参数列表 返回值:无 |
public string[] GetStateRightsList(string wfInstanceID, string stateName) |
功能:获得实例状态的权限列表 参数:wfInstanceID 工作流实例ID |
|
stateName 工作流状态名称 返回值:工作流状态权限列表 |
public string[] GetEventRightsList(string wfInstanceID, string stateName, string eventName) |
功能:获得实例状态中事件的权限列表 参数:wfInstanceID 工作流实例ID |
|
stateName 工作流状态名称 eventName 工作流状态中事件名称 返回值:工作流状态中事件列表权限列表 |
public ArrayList getBussinessStateList(string InstanceID) |
功能:获得工作流实例业务状态列表 参数:InstanceID 工作流实例GUID字符串 返回值:实例业务状态列表 |
public ArrayList getActivityStateList(string InstanceID) |
功能:获得节点Activity自身属性信息列表 参数:InstanceID 工作流实例GUID字符串 返回值:Activity自身属性信息列表 |
public ArrayList getWFInstanceOperList(string InstanceID) |
功能:获得实例操作信息列表 参数:InstanceID 工作流实例GUID字符串 返回值:实例操作信息列表 |
public ArrayList getWFInstanceStateList(string strWFGuid) |
功能:获得实例运行状态列表 参数:InstanceID 工作流实例GUID字符串 返回值:实例运行状态列表 |
|
|
|
|
LocalService 服务是工作流业务流程实现的核心服务,所有的LocalService服务类都继承统一的接口IBaseLocalService,同时每个 LocalService 都继承自己特定的接口,所有的LocalService 对外提供统一的调用方式;
每个针对LocalService的借口必须以[ExternalDataExChange]属性来标记,以保证工作流和LocalService之间能进行数据交换;
数据交互的方式是通过DynamicForm 对象来实现,DynamicForm 是自定义封装用于参数传递的类;
IBaseLocalService 接口代码示例(该接口定义不允许修改):
/// <summary>
/// 所有LocalService 的父类接口,对外保证统一的事件触发方式
/// GeneralXU 07-05-06
/// </summary>
public interface IBaseLocalService
{
void RaiseEvent(DynamicForm form, Guid id);
}
LocalService 自身接口代码示例(该接口,开发人员根据实际的业务需要自己写):
namespace StateMachineLocalService
{
/// <summary>
/// GeneralXU 07-04-12
/// </summary>
[Serializable] //该类可以被序列化,但是不能继承
public class StateMEventArgs : ExternalDataEventArgs
{
private DynamicForm _parameters;
//"base" 关键字指在派生类创建时调用基类的构造函数
public StateMEventArgs(Guid instanceId, DynamicForm parameters)
: base(instanceId)
{
Parameters = parameters;
}
public DynamicForm Parameters
{
get { return _parameters; }
set { _parameters = value; }
}
}
//状态机LocalService接口
[ExternalDataExchange]
public interface IStateMachineService
{
//范型类型的参数,指定事件所生成的事件的数据类型
//同时,EventHandler就是系统类库中声明的一个委托,这里用了委托的方式
event EventHandler<StateMEventArgs> StateCreated;
event EventHandler<StateMEventArgs> StateShipped;
event EventHandler<StateMEventArgs> StateUpdated;
event EventHandler<StateMEventArgs> StateProcessed;
event EventHandler<StateMEventArgs> StateCanceled;
}
}
LocalService 接口类代码示例(该接口类,开发人员根据实际的业务需要自己写):
namespace StateMachineLocalService
{
/// <summary>
/// GeneralXU 07-04-12
/// </summary>
//状态机LocalService类(接口的实现),是工作流对外的一个接口类;这里有委托和范型的使用
public class StateMachineService : IBaseLocalService,IStateMachineService
{
#region IStateMachineService成员声明
public event EventHandler<StateMEventArgs> StateCreated;
public event EventHandler<StateMEventArgs> StateShipped;
public event EventHandler<StateMEventArgs> StateUpdated;
public event EventHandler<StateMEventArgs> StateProcessed;
public event EventHandler<StateMEventArgs> StateCanceled;
#endregion
public StateMachineService()
{
}
public void RaiseStateCreatedEvent(DynamicForm form, Guid instanceId)
{
if (StateCreated != null)
{
StateCreated(null, new StateMEventArgs(instanceId, form));
}
}
public void RaiseStateShippedEvent(DynamicForm form, Guid instanceId)
{
if (StateShipped != null)
{
StateShipped(null, new StateMEventArgs(instanceId, form));
}
}
public void RaiseStateUpdatedEvent(DynamicForm form, Guid instanceId)
{
if (StateUpdated != null)
{
StateUpdated(null, new StateMEventArgs(instanceId, form));
}
}
public void RaiseStateProcessedEvent(DynamicForm form, Guid instanceId)
{
if (StateProcessed != null)
{
StateProcessed(null, new StateMEventArgs(instanceId, form));
}
}
public void RaiseStateCanceledEvent(DynamicForm form, Guid instanceId)
{
if (StateCanceled != null)
{
StateCanceled(null, new StateMEventArgs(instanceId, form));
}
}
#region IBaseLocalService 成员
/// <summary>
/// 公共接口实现引发事件
/// </summary>
/// <param name="form"></param>
/// <param name="id"></param>
public void RaiseEvent(DynamicForm form, Guid id)
{
string eventName = (string)form["eventName"];
switch (eventName)
{
case "CreateState":
RaiseStateCreatedEvent(form, id);
break;
case "ShipState":
RaiseStateShippedEvent(form, id);
break;
case "UpdateState":
RaiseStateUpdatedEvent(form, id);
break;
case "ProcessState":
RaiseStateProcessedEvent(form, id);
break;
case "CancelState":
RaiseStateCanceledEvent(form, id);
break;
default:
break;
}
}
#endregion
}
}
页面名称 |
功能描述 |
WFModelTypeMag.aspx |
实现工作流基础类型的添加; 实现工作流模板的针对类型的归类 |
WFModelListSelMag.aspx |
实现对工作流模板文件的按条件过滤,条件包括:文件名、创建人、创建时间、所属类型、业务描述等 实现对工作流模板的选择调用; |
WFRightSetMag.aspx |
实现对工作流状态和事件权限设置; |
|
|
工作流监控制接口上面提到一些,另外还有一些通过对数据库表的操作来实现;另外还有一些特殊的接口,会根据实际应用中的业务需求提供;
工作流图形化展现,目前改变原来用几个图片简单展示状态的方式,目前采用VML技术动态输出流程(目前处在测试研究阶段),接口会在随后研发中定义出来。