博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

WF4:Workflow Service中Correlation的基本使用

Posted on 2010-01-24 16:49  生鱼片  阅读(2047)  评论(2编辑  收藏  举报

1.关联可以保证消息之间的正确路由,本文举一个简单的例子,首先定义一个流程表单类,如下:

namespace CaryContract

{

    [DataContract]

    public class FlowForm

    {

        [DataMember]

        public Guid FormNum { get; set; }

 

        [DataMember]

        public string FlowStatus { get; set; }

 

        [DataMember]

        public string ApplyName { get; set; }

 

        [DataMember]

        public string ApplyContent { get; set; }

    }

}

2.然后工作流中完成提交申请和审批两个动作,每个动作我们都使用了ReceiveAndSendReply模板,具体设计如下:

clip_image002 

 

clip_image004

clip_image006

3.对应工作流的XAML如下:

<Activity mc:Ignorable="sap" x:Class="CaryService.Workflow1" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:c="clr-namespace:CaryContract;assembly=CaryContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:c1="clr-namespace:CaryContract;assembly=CaryContract" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:s="clr-namespace:System;assembly=mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns:s1="clr-namespace:System;assembly=mscorlib" xmlns:s2="clr-namespace:System;assembly=System" xmlns:s3="clr-namespace:System;assembly=System.Xml" xmlns:s4="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sd1="clr-namespace:System.Data;assembly=System.Data.DataSetExtensions" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:ssa="clr-namespace:System.ServiceModel.Activities;assembly=System.ServiceModel.Activities" xmlns:ssx="clr-namespace:System.ServiceModel.XamlIntegration;assembly=System.ServiceModel" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Sequence sad:XamlDebuggerXmlReader.FileName="c:\users\baby\documents\visual studio 2010\Projects\CaryService\CaryService\Workflow1.xaml" sap:VirtualizedContainerService.HintSize="300,1056">

    <Sequence.Variables>

      <Variable x:TypeArguments="c1:FlowForm" Name="flowApp" />

      <Variable x:TypeArguments="p:CorrelationHandle" Name="flowHandle" />

    </Sequence.Variables>

    <sap:WorkflowViewStateService.ViewState>

      <scg3:Dictionary x:TypeArguments="x:String, x:Object">

        <x:Boolean x:Key="IsExpanded">True</x:Boolean>

      </scg3:Dictionary>

    </sap:WorkflowViewStateService.ViewState>

    <Sequence DisplayName="" sap:VirtualizedContainerService.HintSize="278,446">

      <Sequence.Variables>

        <Variable x:TypeArguments="p:CorrelationHandle" Name="__handle1" />

      </Sequence.Variables>

      <sap:WorkflowViewStateService.ViewState>

        <scg3:Dictionary x:TypeArguments="x:String, x:Object">

          <x:Boolean x:Key="IsExpanded">True</x:Boolean>

          <x:Boolean x:Key="IsPinned">False</x:Boolean>

        </scg3:Dictionary>

      </sap:WorkflowViewStateService.ViewState>

      <p:Receive x:Name="__ReferenceID0" CanCreateInstance="True" CorrelatesWith="[flowHandle]" sap:VirtualizedContainerService.HintSize="256,92" OperationName="SendFlow" ServiceContractName="FlowService">

        <p:Receive.CorrelatesOn>

          <p:XPathMessageQuery x:Key="key1">

            <p:XPathMessageQuery.Namespaces>

              <ssx:XPathMessageContextMarkup>

                <x:String x:Key="xg0">http://schemas.datacontract.org/2004/07/CaryContract</x:String>

                <x:String x:Key="xgSc">http://tempuri.org/</x:String>

              </ssx:XPathMessageContextMarkup>

            </p:XPathMessageQuery.Namespaces>sm:body()/xgSc:SendFlow/xgSc:p1/xg0:FormNum</p:XPathMessageQuery>

        </p:Receive.CorrelatesOn>

        <p:Receive.CorrelationInitializers>

          <p:RequestReplyCorrelationInitializer CorrelationHandle="[__handle1]" />

        </p:Receive.CorrelationInitializers>

        <p:ReceiveParametersContent>

          <OutArgument x:TypeArguments="c1:FlowForm" x:Key="p1">[flowApp]</OutArgument>

        </p:ReceiveParametersContent>

      </p:Receive>

      <Assign sap:VirtualizedContainerService.HintSize="256,58">

        <Assign.To>

          <OutArgument x:TypeArguments="s1:Guid">[flowApp.FormNum]</OutArgument>

        </Assign.To>

        <Assign.Value>

          <InArgument x:TypeArguments="s1:Guid">[Guid.NewGuid()]</InArgument>

        </Assign.Value>

      </Assign>

      <p:SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendReplyToReceive" sap:VirtualizedContainerService.HintSize="256,92">

        <p:SendParametersContent>

          <InArgument x:TypeArguments="x:String" x:Key="result">[flowApp.FormNum.ToString() + "-" + flowApp.ApplyName + "-" + flowApp.ApplyContent + "-" + flowApp.FlowStatus]</InArgument>

        </p:SendParametersContent>

      </p:SendReply>

    </Sequence>

    <Sequence DisplayName="" sap:VirtualizedContainerService.HintSize="278,446">

      <Sequence.Variables>

        <Variable x:TypeArguments="p:CorrelationHandle" Name="__handle1" />

        <Variable x:TypeArguments="s1:Guid" Name="flowID" />

        <Variable x:TypeArguments="x:String" Name="flowStatus" />

      </Sequence.Variables>

      <sap:WorkflowViewStateService.ViewState>

        <scg3:Dictionary x:TypeArguments="x:String, x:Object">

          <x:Boolean x:Key="IsExpanded">True</x:Boolean>

          <x:Boolean x:Key="IsPinned">False</x:Boolean>

        </scg3:Dictionary>

      </sap:WorkflowViewStateService.ViewState>

      <p:Receive x:Name="__ReferenceID1" CorrelatesWith="[flowHandle]" sap:VirtualizedContainerService.HintSize="256,92" OperationName="ApproveFlow" ServiceContractName="FlowService">

        <p:Receive.CorrelatesOn>

          <p:XPathMessageQuery x:Key="key1">

            <p:XPathMessageQuery.Namespaces>

              <ssx:XPathMessageContextMarkup>

                <x:String x:Key="xgSc">http://tempuri.org/</x:String>

              </ssx:XPathMessageContextMarkup>

            </p:XPathMessageQuery.Namespaces>sm:body()/xgSc:ApproveFlow/xgSc:pid</p:XPathMessageQuery>

        </p:Receive.CorrelatesOn>

        <p:Receive.CorrelationInitializers>

          <p:RequestReplyCorrelationInitializer CorrelationHandle="[__handle1]" />

        </p:Receive.CorrelationInitializers>

        <p:ReceiveParametersContent>

          <OutArgument x:TypeArguments="s1:Guid" x:Key="pid">[flowID]</OutArgument>

          <OutArgument x:TypeArguments="x:String" x:Key="pstatus">[flowStatus]</OutArgument>

        </p:ReceiveParametersContent>

      </p:Receive>

      <Assign sap:VirtualizedContainerService.HintSize="256,58">

        <Assign.To>

          <OutArgument x:TypeArguments="x:String">[flowApp.FlowStatus]</OutArgument>

        </Assign.To>

        <Assign.Value>

          <InArgument x:TypeArguments="x:String">[flowStatus]</InArgument>

        </Assign.Value>

      </Assign>

      <p:SendReply Request="{x:Reference __ReferenceID1}" DisplayName="SendReplyToReceive" sap:VirtualizedContainerService.HintSize="256,92">

        <p:SendParametersContent>

          <InArgument x:TypeArguments="x:String" x:Key="result">[flowApp.FormNum.ToString() + "-" + flowApp.ApplyName + "-" + flowApp.ApplyContent + "-" + flowApp.FlowStatus]</InArgument>

        </p:SendParametersContent>

      </p:SendReply>

    </Sequence>

  </Sequence>

</Activity>

4.我们使用WorkflowServiceHost来宿主工作流如下:

namespace CaryService

{

    class Program

    {

        static void Main(string[] args)

        {

            string baseAddress = "http://localhost:8081/FlowService";

            using (WorkflowServiceHost shost = new WorkflowServiceHost(new Workflow1(), new Uri(baseAddress)))

            {

                shost.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });

                shost.Open();

                Console.WriteLine("FlowService is listening:" + baseAddress);

                Console.ReadLine();

            }

        }

    }

}

5.客户端使用WebForm,WebForm1.aspx对应的cs文件的代码如下:

namespace CaryClient

{

    public partial class WebForm1 : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

        }           

        protected void Button1_Click(object sender, EventArgs e)

        {

            FlowForm flow = new FlowForm();

            ServiceReference1.FlowServiceClient fs = new ServiceReference1.FlowServiceClient();   

            flow.ApplyName = TextBox1.Text;

            flow.ApplyContent = TextBox2.Text;

            flow.FlowStatus = "";

            ListBox1.Items.Add(fs.SendFlow(flow));          

        }

        protected void Button2_Click(object sender, EventArgs e)

        {

            FlowForm flow = new FlowForm();

            flow.FlowStatus = "";

            ServiceReference1.FlowServiceClient fs = new ServiceReference1.FlowServiceClient();   

            ListBox1.Items.Add(fs.ApproveFlow(flow.FormNum,flow.FlowStatus));

        }

    }

}

6.执行结果如下:

clip_image008