上篇asp.net中的报销多级审批工作流 ,提到参考了网上一个具体的项目,项目中用状态机工作流完成,基于学习的原因,我采用顺序工作流,事件驱动方式实现了同样的功能。后来学习到了状态机,觉的状态机实现也特别方便。 下面我分享下状态机工作流中几个主要的活动。
顺序工作流与状态机工作流的区别:
顺序工作流是一种可以预测,流程比较固定,而状态机工作流不可预测,主要靠外部事件驱动来实现,对外的交互比较多,系统的状态需要外部事件的触发来改变。
状态机工作流活动图:
1:State Activity,在状态机工作流中代表了一个具体的状态,这种状态机以事件驱动为主,和之前顺序工作流中的事件驱动有点类似。在整个状态机工作流中,会有一个初始化的State Activity和一个表示完成的State Activity,我们从工具箱中拉一个State Activity,然后单击右键,出现如下图,绿色的表示初始化State Activity,而红色的表示完成的State Activity,分别会在State Activity的左上角有相应的标示。
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类详细代码如下:
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->
public class WorkflowWrapper:IDisposable
{
static WorkflowRuntime runtime;//运行时
static WorkflowInstance instance;//实例
static ExternalDataExchangeService service;//外部数据交换服务
static WorkflowPersistenceService perService;//持久化服务
public static BLL_Approve project;//实现接口类
/// <summary>
/// 启动工作流引擎
/// </summary>
public void StartWorkFlowRuntime()
{
if (runtime != null)
{
try
{
//启动工作流引擎
runtime.StartRuntime();
}
catch(Exception ex)
{
this.InitWorkFlowRuntime();
}
}
else
{
this.InitWorkFlowRuntime();
}
}
/// <summary>
/// 初始化工作流引擎
/// </summary>
public void InitWorkFlowRuntime()
{
runtime = new WorkflowRuntime();
service = new ExternalDataExchangeService();
project = new BLL_Approve();
perService = new SqlWorkflowPersistenceService(ConfigurationManager.
ConnectionStrings["perstr"].ConnectionString);
if (runtime.GetService(service.GetType()) == null)//服务不能重复加入
{
runtime.AddService(service);
}
if (runtime.GetService(perService.GetType()) == null)
{
//加入持久化服务
runtime.AddService(perService);
}
if (service.GetService(project.GetType()) == null)
{
//将此类加入外部数据交换服务
service.AddService(project);
}
//工作流闲置事件
runtime.WorkflowIdled += OnWorkflowIdled;
//启动工作流引擎
runtime.StartRuntime();
}
/// <summary>
/// 工作流闲置事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnWorkflowIdled(object sender, WorkflowEventArgs e)
{
e.WorkflowInstance.TryUnload();//将内存数据持久化到数据库中
}
/// <summary>
/// 创建一个工作流实例
/// </summary>
public void CreateWorkFlowInstance()
{
//确保启动了工作流引擎
this.StartWorkFlowRuntime();
//创建一个工作流实例
string sWorkFlowType =
ConfigurationManager.AppSettings["WorkFlowType"].Trim();
switch (sWorkFlowType)
{
case "1":
instance = runtime.CreateWorkflow(typeof(
ApproveWorkFlow.MyWorkFlow.Workflow1));
break;
case "2":
instance = runtime.CreateWorkflow(typeof(
ApproveWorkFlow.MyWorkFlowStateMachine .Workflow1));
break;
}
}
/// <summary>
/// 返回一个工作流实例
/// </summary>
/// <returns></returns>
public WorkflowInstance GetWorkflowInstance()
{
if (instance == null)
{
this.CreateWorkFlowInstance();
}
return instance;
}
/// <summary>
/// 启动工作流实例
/// </summary>
public void StartWorkFlowInstance()
{
this.CreateWorkFlowInstance();
instance.Start();
}
/// <summary>
/// 加载一个已经存在的未完成的工作流实例
/// </summary>
/// <param name="_Guid"></param>
public WorkflowInstance GetGetWorkflowById(Guid _Guid)
{
//确保启动了工作流引擎
this.StartWorkFlowRuntime();
return runtime.GetWorkflow(_Guid);
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
if (runtime != null)
{
//停止工作流引擎
runtime.StopRuntime();
//释放占用的资源
runtime.Dispose();
}
}
}
小结:无论是之前的顺序工作流还是现在的状态机工作流,都是事件驱动性工作流,外部调用上没有任何区别,唯一的区别就在创建工作流实例,我们看下上面的创建工作流实例的方法,为了演示方便,我在web.config文件中加了一个配置节,用来控制创建的工作流类型:
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><!--工作流类型 1:顺序工作流 2:状态机工作流-->
<add key ="WorkFlowType" value ="2"/>
经过这样的封装后我们来看下页面层的代码:页面中只会出现业务逻辑层的类,WorkFlow相关的类尽量不要直接出现,代码的复用也得到了提高,第二部分为提交事件的代码:
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--> 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();
}
用户的提交事件代码:
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->
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();
注:
原项目地址:http://download.csdn.net/down/948601/oxch2008
相关推荐
asp.net开发报销多级审批工作流 (状态机版本).doc
asp.net开发OA系统中的报销多级审批工作流(顺序工作流).doc
用Asp.Net开发的一种审批流程,可以用来查看审批的一种流程。
源码实例,状态机工作流实例报销审批流程,ASP.NET
通过asp.net core 页面发起Elsa工作流 工作流持久化,手工启动
asp.net 服务端 多级 导航条asp.net 服务端 多级 导航条asp.net 服务端 多级 导航条asp.net 服务端 多级 导航条asp.net 服务端 多级 导航条asp.net 服务端 多级 导航条asp.net 服务端 多级 导航条
用asp.net MVC5开发的工作流引擎,本源码包含可视化流程设计器,表单设计器。适合对象:需要从事OA办公系统、CRM客户关系系统、HR人事管理系统的你参考学习之用,同时你还可以学习现在流行的MVC。
基于asp.net+C#开发的工作流平台superflow最新版本V6.5-20150104,该平台具有独立的工作流引擎,提供纯BS结构的工作流程设计器,工作流表单设计器,以及提供工作流审批系统所需要的应用系统二次开发框架,提供强大的...
在项目中使用到的流程自定义及审批工作流源码,asp.net
asp.net工作流状态机实例 提供了一个.net的状态转换实例,是很好的 工作流的学习实例
工作流实例,Asp.net,工作流程下载,附有数据库
32Asp.net工作流
基于asp.net+C#开发的superflow工作流平台最新版本V5.5-20130402
这是在asp.net下用WF开发的工作流实例,在网上找的,如果有可能的话,希望能帮到大家
ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP.NET入门经典ASP...
运行环境:vs+sql server。适用于课程设计或者毕业设计参考使用
基于ASP.NET的工作流批核系统(.NET 3.5框架的WF技术实现)
基于ASP.NET的工作流系统(.NET 3.5框架的WF技术实现)
公司的上一个项目需要自定义工作流和审批流,那就需要一个可视化的定义工作流和审批流的工具,找了很多都不太适合我们的项目,项目是用Asp.net开发,需要在网页里实现工作流的自定义,说白了就是写一个程序,可以...
ASP.NET中实现二级或多级域名ASP.NET中实现二级或多级域名(修改UrlRewrite) 大家应该知道,微软的URLRewrite能够对URL进行重写,但是也只能对域名之后的部分进行重写,而不能对域名进行重写,如:可将 ...