上篇
Asp.Net 中的报销多级审批工作流 ,提到参考了网上一个具体的项目,项目中用状态机工作流完成,基于学习的原因,我采用顺序工作流,事件驱动方式实现了同样的功能。后来学习到了状态机,觉的状态机实现也特别方便。 下面我分享下状态机工作流中几个主要的活动。
顺序工作流与状态机工作流的区别:
顺序工作流是一种可以预测,流程比较固定,而状态机工作流不可预测,主要靠外部事件驱动来实现,对外的交互比较多,系统的状态需要外部事件的触发来改变。
状态机工作流活动图: 附件:
2009-2-27-1.jpg 1:State Activity,在状态机工作流中代表了一个具体的状态,这种状态机以事件驱动为主,和之前顺序工作流中的事件驱动有点类似。在整个状态机工作流中,会有一个初始化的State Activity和一个表示完成的State Activity,我们从工具箱中拉一个State Activity,然后单击右键,出现如下图,绿色的表示初始化State Activity,而红色的表示完成的State Activity,分别会在State Activity的左上角有相应的标示。
附件:
2009-2-27-2.jpg 2:EventDriven Activity,做为State Activity的子活动,状态中的所有事件都存放在这。
3:HandleExternalEvent activity,这就是具体的外部事件活动,它即可以用在顺序工作流中,也可以用在状态机工作流中。设置方法可参考上篇文章asp.net中的报销多级审批工作流。
4:SetState Activity,外部事件的执行会使状态机工作流中的状态发生变化,说的通俗点就是告诉状态机下一步的动向。我们只要设置它的一个关键属性就行:TargetStateName,这个属性是指向状态机中一个已经存在的具体状态。设置好后就会发生在设计器中出现连接箭头。
宿主调用代码的封装: 我发现源项目中没有封装对于WorkflowRuntime和WorkflowInstance的使用,每个审批页面都会出现很多初始化工作流引擎, 创建工作流实例的代码,这里我在公共层中封装了一个WorkflowWrapper类。主要方法有:
1:InitWorkFlowRuntime,初始化工作流引擎。
2:StartWorkFlowRuntime,启动工作流引擎。
3:OnWorkflowIdled,工作流闲置事件。
4:CreateWorkFlowInstance,创建一个工作流实例。
5:GetWorkflowInstance,返回一个工作流实例。
6:StartWorkFlowInstance,启动工作流实例。
7:GetGetWorkflowById,加载一个已经存在的未完成的工作流实例。
8:Dispose,释放资源。
WorkflowWrapper类详细代码如下:
小结:无论是之前的顺序工作流还是现在的状态机工作流,都是事件驱动性工作流,外部调用上没有任何区别,唯一的区别就在创建工作流实例,我们看下上面的创建工作流实例的方法,为了演示方便,我在web.config文件中加了一个配置节,用来控制创建的工作流类型:
<!--工作流类型 1:顺序工作流 2:状态机工作流-->
<add key ="WorkFlowType" value ="2"/>
经过这样的封装后我们来看下页面层的代码:页面中只会出现业务逻辑层的类,WorkFlow相关的类尽量不要直接出现,代码的复用也得到了提高,第二部分为提交事件的代码:
- BllExpense Bll;
- static WorkflowWrapper _WorkflowWrapper = new WorkflowWrapper();
- protected void Page_Load(object sender, EventArgs e)
- {
- Bll = new BllExpense();
- if (!IsPostBack)
- {
- ViewState["userName"] = Request["name"];
- this.tbName.Text = ViewState["userName"].ToString();
- BindData(ViewState["userName"].ToString());
- }
- //初始化,启动工作流引擎
- _WorkflowWrapper.StartWorkFlowRuntime();
- }
复制代码用户的提交事件代码:
- Guid workflowId = new Guid(this.tbNo.Text);
- //读取一个未完成的工作流实例
- WorkflowInstance _WorkflowInstance=
- _WorkflowWrapper.GetGetWorkflowById(workflowId);
- ExpenseAccountInfo info = new ExpenseAccountInfo( workflowId, Convert.ToDecimal(this.tbMoney.Text),
- this.tbName.Text, DateTime.Now.ToShortDateString(),
- "结束", this.tbNotes.Text);
- //触发工作流事件
- WorkflowWrapper.project.RaiseStaffDelete(info);
- //从数据库中查找作流,并加入内存中(持久化的作用)
- _WorkflowInstance.TryUnload();
- //释放资源
- _WorkflowWrapper.Dispose();
复制代码(文/
ASPNET2008)
项目代码下载: