Windows workflow foundation之旅(三)——指南2(创建状态机工作流)(上)

Windows workflow foundation之旅(三)——指南2(创建状态机工作流)(上)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

翻译自:ms-help://MS.WinWF.v1.EN/WinWF_GettingStarted/html/8b6344bc-c879<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />-41c5-babf-74e91c34d281.htm

 

状态机工作流是为事件驱动的工作场景设计的。一个状态机工作流包含两个或两个以上的状态,且任意时刻只有一个处于激活状态。在这一节中,我们将创建一个基于状态机的工作流,这个工作流将通过其内部不同的状态,来处理宿主程序提交的订单。初始状态为WaitForOrderState只要宿主程序提交了一个新订单,这个状态就会执行。当收到一个新订单后,进入OrderProcessing状态开始处理订单。最后一个状态就是OrderCompletedState。在这个过程中,不同的状态将会与宿主程序交互。

 

创建一个状态机工作流

 

一个状态机工作流可以继承从StateMachineWorkflow类,这个类中已经实现了状态机工作流的大部分功能。一旦你继承了这个类,你就可以开始在工作流中加入所需的状态,并使用SetState活动或事件驱动的活动如EventSink把这些状态连接起来。以下的代码就是我们的工作流类OrderProcessingWorkflow,这个类是接下来整个示例程序的基础。你可能已经注意到了,类中声明了两个变量。这两个变量是用来存贮当前订单信息的,这些信息将会在整个流程中用到。

None.gif using  System;
None.gif
using  System.Workflow.ComponentModel;
None.gif
using  System.Workflow.Runtime;
None.gif
using  System.Workflow.Activities;
None.gif
using  System.Workflow.Activities.Rules;
None.gif 
None.gif
namespace  Microsoft.Samples.Workflow.Quickstarts.StateMachine
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public partial class OrderProcessingWorkflow : StateMachineWorkflow
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private string orderId;
InBlock.gif        
private string itemStatus;
InBlock.gif        
InBlock.gif        
public OrderProcessingWorkflow()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            InitializeComponent();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
private void InitializeComponent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

 

创建活动和参数绑定

 

WWF中有两个类ActivityBindParameterBinding,是专门用来将活动中的变量,绑定到方法调用所需的参数上的。这个方法定义在一个接口中,接口的实现就是注册到工作流中的服务。在我们的程序中,我们将把当前订单的orderIdstatus的值传递进去。以下的代码示例了如何创建和联系工作流的私有变量和参数。这些参数将用来根据当前工作流的状态来更新宿主。在稍后创建状态活动时,我们将用到这些绑定对象。

 

开始创建活动和参数绑定

 

1.  定义一个私有变量

类型

名称

ActivityBind

orderIdActivityBind

ParameterBinding

orderIdParameterBinding

ActivityBind

itemStatusActivityBind

ParameterBinding

itemStatusParameterBinding

2.  以下代码示例了如何创建ActivityBindParameterBinding,以及怎样和私有变量绑定。

None.gif //
None.gif
//  Binding variables
None.gif
//
None.gif
orderIdActivityBind  =   new  ActivityBind();
None.giforderIdParameterBinding 
=   new  ParameterBinding();
None.gifitemStatusActivityBind 
=   new  ActivityBind();
None.gifitemStatusParameterBinding 
=   new  ParameterBinding();
None.gif 
None.giforderIdActivityBind.ID 
=   " /Workflow " ;
None.giforderIdActivityBind.Path 
=   " orderId " ;
None.giforderIdParameterBinding.ParameterName 
=   " orderId " ;
None.giforderIdParameterBinding.SetBinding(System.Workflow.ComponentModel.ParameterBinding.ValueProperty,
None.gif    ((System.Workflow.ComponentModel.Bind)(orderIdActivityBind)));
None.gif 
None.gifitemStatusActivityBind.ID 
=   " /Workflow " ;
None.gifitemStatusActivityBind.Path 
=   " itemStatus " ;
None.gifitemStatusParameterBinding.ParameterName 
=   " newStatus " ;
None.gifitemStatusParameterBinding.SetBinding(System.Workflow.ComponentModel.ParameterBinding.ValueProperty,
None.gif((System.Workflow.ComponentModel.Bind)(itemStatusActivityBind)));

 

构造WaitingForOrder状态

 

这第一个状态监听来自宿主的事件,这个事件通知工作流一个新的订单已经被提交了,应该马上处理它。当你创建状态时,状态的第一个子活动必须是StateInitialization活动或实现了IEventActivity接口的活动。这里的WaitForOrderState采用了后者,因为这个状态是由宿主程序的事件激活的。

EventSink活动是用来监听注册在WWF运行库中的服务的事件的,在我们的程序中,这个服务由宿主程序提供。我们在工作流中定义了IOrderingService接口,这个接口稍后将由宿主程序实现。

None.gif using  System;
None.gif
using  System.Workflow.ComponentModel;
None.gif
using  System.Workflow.Runtime.Messaging;
None.gif 
None.gif
namespace  Microsoft.Samples.Workflow.Quickstarts.StateMachine
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    [Serializable]
InBlock.gif    
public class NewOrderEventArgs : WorkflowMessageEventArgs
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private string item;
InBlock.gif        
private int quantity;
InBlock.gif 
InBlock.gif        
public NewOrderEventArgs(Guid instanceId, string item, int quantity)
InBlock.gif            : 
base(instanceId)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.item = item;
InBlock.gif            
this.quantity = quantity;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string Item
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn item; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ item = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public int Quantity
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn quantity; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ quantity = value; }
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    [DataExchangeService]
InBlock.gif    
public interface IOrderingService
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
void ItemStatusUpdate( string orderId, string newStatus);
InBlock.gif        
event EventHandler<NewOrderEventArgs> NewOrder;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

 

一旦EventSink活动处理了触发事件后,一个状态消息需要通过IOrderingInterface发回宿主程序。工作流需要调用接口中的ItemStatusUpdate方法,并传递orderIdnewStatues参数。而调用接口方法的工作,就交给InvokeMethodActivity活动了。我们指定活动的InterfaceType参数为我们需要的服务接口,MethodName属性设为要调用的服务接口中的方法名称,然后在ParameterBindings中加入之前构造好的参数绑定,最后为活动的MethodInvoking事件指定一个事件处理程序,用来改变当前订单的状态。因为我们已经把orderIdnewStatus参数绑定到了私有变量orderIditemStatus上,所以为ItemStatusUpdate方法传递参数的过程是由WWF运行库自动完成的。

更新完成之后,WaitingForOrderState状态已经准备好转移下一个状态——OrderOpenState(译者注:这里错了,应该是OrderPrecessingState)状态。SetState活动是专门负责状态转移的。把一个SetState活动加入到EventDriven的最后一环,当一切处理完后,SetState活动将执行,并立马跳转到指定的下一个状态。

 

开始构造WaitForOrderState

 

1.  定义5个私有变量

类型

名称

EventSinkActivity

newOrderEventSink

InvokeMethodActivity

updatestatusOrderReceived

SetState

setStateOrderProcessing

EventDriven

eventDriven1

State

WaitingForOrderState

2.  用默认构造函数实例化以上变量

以下代码演示了如何构造WaitForOrderState。先是EventSinkActivity来处理宿主事件,然后InvokeMethodActivity来改变当前订单状态,并更新宿主状态。最后,SetState活动将WaitForOrder状态转移到OrderPrecessing状态。把这三个活动就依次加入到EventDriven活动的子活动中。

None.gif //
None.gif
//  WaitingForOrder State
None.gif
//
None.gif
this .newOrderEventSink  =   new  System.Workflow.Activities.EventSinkActivity();
None.gif
this .newOrderEventSink.EventName  =   " NewOrder " ;
None.gif
this .newOrderEventSink.ID  =   " newOrderEventSink " ;
None.gif
this .newOrderEventSink.InterfaceType  =   typeof (Microsoft.Samples.Workflow.Quickstarts.StateMachine.IOrderingService);
None.gif
this .newOrderEventSink.Roles  =   null ;
None.gif 
None.gif
this .updatestatusOrderReceived  =   new  System.Workflow.Activities.InvokeMethodActivity();
None.gif
this .updatestatusOrderReceived.ID  =   " updatestatusOrderReceived " ;
None.gif
this .updatestatusOrderReceived.InterfaceType  =   typeof (Microsoft.Samples.Workflow.Quickstarts.StateMachine.IOrderingService);
None.gif
this .updatestatusOrderReceived.MethodName  =   " ItemStatusUpdate " ;
None.gif
this .updatestatusOrderReceived.ParameterBindings.Add(orderIdParameterBinding);
None.gif
this .updatestatusOrderReceived.ParameterBindings.Add(itemStatusParameterBinding);
None.gif
this .updatestatusOrderReceived.MethodInvoking  +=   new  System.EventHandler( this .OrderReceived);
None.gif 
None.gif
this .setStateOrderProcessing  =   new  System.Workflow.Activities.SetState();
None.gif
this .setStateOrderProcessing.ID  =   " setStateOrderProcessing " ;
None.gif
this .setStateOrderProcessing.TargetState  =   " OrderProcessingState " ;
None.gif 
None.gif
this .eventDriven1  =   new  System.Workflow.Activities.EventDriven();
None.gif
this .eventDriven1.Activities.Add( this .newOrderEventSink);
None.gif
this .eventDriven1.Activities.Add( this .updatestatusOrderReceived);
None.gif
this .eventDriven1.Activities.Add( this .setStateOrderProcessing);
None.gif
this .eventDriven1.ID  =   " eventDriven1 " ;
None.gif 
None.gif
this .WaitingForOrderState  =   new  System.Workflow.Activities.State();
None.gif
this .WaitingForOrderState.Activities.Add( this .eventDriven1);
None.gif
this .WaitingForOrderState.ID  =   " WaitingForOrderState " ;

 

你可以在InvokeMethodActivity活动执行的前一刻,加入一些附加的逻辑。只要为MethodInvoking事件指定一个处理程序,就能做到这一点。以下的代码就是MethodInvoking事件的处理程序。它为itemStatusorderId变量指定了新的值。事件处理程序的指定,已经在上面的代码中做了。

None.gif private   void  OrderReceived( object  sender, EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    itemStatus 
= "Received order";
InBlock.gif    orderId 
= Guid.NewGuid().ToString();
ExpandedBlockEnd.gif}

手指冻僵了~ 让我缓一缓先 02.gif


Windows workflow foundation之旅(四)——指南2(创建状态机工作流)(下)

转载于:https://www.cnblogs.com/windwolfreal/archive/2005/12/18/299629.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值