简单状态机Workflow基于Web应用

一、实现目的
1 、在Web中托管Workflow引擎实现工作流流转。
2、使用持久化的方式存放工作流实例状态。
二、基本原形
报销流程(网上有很成熟的基于工作流的报销流程,我还在这里显摆,唉!)
三、使用到的核心类
WorkflowRuntime、ExternalDataExchangeService、WorkflowInstance、WorkflowPersistenceService
分别在dotnet3.0的一下命名空间中:
System.Workflow.Runtime、System.Workflow.Activities、System.Workflow.Runtime.Hosting
四、工作流项目设计

1、报销流程还是沿用了网上广为流传的那个报销流程的模式(细节上也没有太大的差别),这里简单描述一下:报销者提交报销信息——〉部门经理审批——〉副总经理审批(如果数目小于1000元跳过此环节)——〉财务经理审批——〉出纳确认——〉结束,如果在除提交环节的任何一个环节审批不通过则将打回到提交者进行提交的初始状态。该例子中使用了状态机模式(个人认为状态机的Workflow可以很好的满足我以前开发中的大多数需求)。
2、使用VS2005进行Workflow开发的基本条件网上很多,这里简单的说一下:
dotnetfx3、Visual Studio 2005 Extensions for Windows Workflow Foundation (CHS)[都可以从官方下载]
3、安装好后会在项目模板中出现专门为Workflow工程开发所提供的几个模板


我个人平时喜欢建立带有控制台的,那样调试很方便,当然如果那样做了的话后来还需要再创建一个基于库的,把那些代码再粘贴过去,因为控制台的bin文件夹里只有exe文件,不能让其他项目进行引用(不过可能有其他的方法我不知道)
4、在工具箱中选择创建流程的各种活动Actives在本例中只适用到了五种State、EventDriven、HandleExternalEvent、SetSate、IfElse


其中State就是状态机中的每个状态的最大容器(当然在设计工作流的时候也可以把一些Actives放在State之外,比如EventDriven,但我还不知道放在状态之外的用处),我设计的其他Actives都是在State里面的。其实我个人使用Active时那些能放在另外一些里面都是通过将他们托放看能不能实现来判断的。

5、根据我的业务流程,在这个例子中总共使用到了6种状态,起始[InitState]和结束[EndState]好像是状态机工作流中必须的两个状态,而且好像能有多个起始状态,结束状态之有一个。此外在该例中还有部门经理审批状态[DManagerState]、副总审批状态[GManagerState]、财务经理审批状态[FManagerState]、出纳确认状态[CashierState](本人的状态分解可能在逻辑上不甚合理,请谅解)。每个状态中都有通过事件进行驱动的EventDriven活动(一个为审批通过触发的事件,一个为审批未通过),还有用来设置下一个进入某个状态的SetState活动。只有在部门经理审批状态中添加了判断报销金额再进行环节流转的Actives。包含关系大概为State活动中包含(拖放)EventDrive活动,EventDrive活动中包含(拖放)HandleExternalEvent、SetSate、IfElse活动。
(一个状态图片)

(进入EventDriven的图片)

(部门经理审批通过触发的EventDriven中判断金额进行状态选择流转的图片)

6、在工作流图形定制界面中除了将所有的Actives拖入放置好以外,还需要对每个Actives进行设置。几种类型Active的大致设置方法为:
State、EventDriven活动只需要进行名称的设置就可以了因为他们可能只是做其他事件或者操作方式的一个容器,不提供什么方法。
HandleExternalEvent活动需要设置需要处理的外部事件,这些外部事件需要在一个定义了很多事件类型的接口来选择。其实就是我们需要定义一个接口,在接口中定义需要在HandleExternalEvent中调用的事件,然后再实现这个接口,在宿主环境中调用接口的实现类来对Workflow引擎发送事件消息,HandleExternalEvent事件在得到这个消息之前是等待状态,也就是说会引发workflowRuntime的WorkflowIdled事件(我们会在这里处理工作流持久化)。HandleExternalEvent得到这个事件消息之后就会往下执行了。因此我们需要设置HandleExternalEvent活动的一下两个属性值InterfaceType和EventName,其中InterfaceType是我们定义的那个接口,EventName是我们在接口中定义的用来为特定HandleExternalEvent进行触发的事件。我们也可以通过使用Invoked来在工作流中处理一些需要的操作。

IfElse活动作为一个容器只需要设置名称,其中需要特别注意的是活动中所包含的两个分支,每个分支都可以绑定进行判断的方法。也可以只在左边的分支上进行条件判断,条件判断可以选择使用“Declarative Rule Condition”申明规则条件(本例中未使用,本人也不太清楚怎么用),还有一个“Code Condition”进行判断方法的绑定,本例中使用这种。选择后可以展开Condition属性将自己写好的条件方法代码绑定。

(IfElse活动)

(IfElse分支属性)

 

SetState活动只需要设置它的名称和TargetStateName属性,该属性的作用是选择下一步要流入的状态名称

7、在工作流代码文件中需要完成IfElse活动中需要的条件判断方法和一个用来接收从宿主(hosting)环境中传入的用来进行报销金额是否大于1000元的参数属性。
在工作流设计的“解决方案资源管理器”中选择 “查看代码”,加入以上代码,并最终绑定IfElse活动的Condition属性。
8、为每个需要接收事件的HandleExternalEvent活动定义一个统一的ExternalDataExchangeService类型接口,并且实现该接口,这样可以在宿主环境中使用接口实现类的实例同工作流引擎通信。
9、在整个解决方案中创建新的Windows类库项目,本例中创建名称为ExtendServiceInstance的项目
10、在解决方案中创建一个以[ExternalDataExchange]为属性的接口,本例中文件名称为ICharge
11、创建实现该接口的类,本例中文件名称为Charge

using  System;
using  System.ComponentModel;
using  System.ComponentModel.Design;
using  System.Collections;
using  System.Drawing;
using  System.Workflow.ComponentModel.Compiler;
using  System.Workflow.ComponentModel.Serialization;
using  System.Workflow.ComponentModel;
using  System.Workflow.ComponentModel.Design;
using  System.Workflow.Runtime;
using  System.Workflow.Activities;
using  System.Workflow.Activities.Rules;

namespace  Workflow
{
    
public   sealed  partial  class  Workflow: StateMachineWorkflowActivity
    {
        
//  报销金额[以后有了Orcas就不需要定义这个变量了]
         private   string  _strMoneyNum  =   default ( string );

        
//  报销金额[属性]
         public   string  MoneyNum
        {
            
get
            {
                
return  _strMoneyNum;
            }
            
set
            {
                _strMoneyNum 
=  value;
            }
        }

        
public  Workflow()
        {
            InitializeComponent();
        }

        
///   <summary>
        
///  IfElse活动左分支的Code Condition中绑定的方法
        
///   </summary>
        
///   <param name="sender"> 发送对象 </param>
        
///   <param name="e"> 注意这里的事件数据类型必须为ConditionalEventArgs </param>
         public   void  GManagerOrFManager( object  sender, ConditionalEventArgs e)
        {
            
//  设置e中需要给工作流返回的bool参数
             i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值