65.9K
CodeProject 正在变化。 阅读更多。
Home

在 WF4 中建立多个 RECEIVE 之间的关联

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

2010年1月22日

CPOL

7分钟阅读

viewsIcon

41123

downloadIcon

802

一个简单的程序来理解 WF4 中的关联。

引言

我的目标是通过一个简单的应用程序介绍 WF4 中固有的关联(Correlation)功能。您需要安装 VS 2010 B2 才能探索附带的代码。我在这里讨论的关联是 WF 服务多个接收(receives)之间的关联。在早期版本中,我们必须使用 GUID 来显式建立关联。

创建关联应用程序的步骤

创建关联 WF4 应用程序涉及以下步骤。

  1. 创建数据实体库。
  2. 创建 WF 服务。
  3. 创建客户端应用程序来调用/使用 WF 服务。

场景

我选择的场景非常简单,以便于理解关联逻辑。在 WF4 中,您可以使用任何数据成员(用于唯一标识实例)来创建关联。我们以一个客户注册应用程序为例,该应用程序首先知道客户的名字,然后稍后更新姓氏。所以,显然,我们需要两个(2)个接收活动。

步骤 1:创建数据实体库

让我们开始创建 WF 服务和客户端之间共享的数据实体库。这个实体库将有 3 个 private 成员和 3 个 public 属性来访问和赋值。

  1. 启动 VS 2010 B2。
  2. 文件 -> 打开 -> 新建项目 -> 选择 VC# -> 类库,并将其命名为 Customer
  3. Class1.cs 重命名为 Customer.cs,并添加对 System.Runtime.Serialization 类的引用。
  4. 在代码中,使用“using”语句引用该类。在类声明的顶部添加 [DataContract] 属性。添加三个 private 成员以及用于名字、客户 ID 和姓氏的 Public get, set 属性。在每个属性的顶部添加 [DataMember] 属性。

您的代码应如下所示...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization; 
namespace Customer
{
   [DataContract]
    public class Customer
    {
        private string _firstName;
        private string _lastName;
        private Int32 _customerID;

        [DataMember]
        public string FirstName { get { return this._firstName; } 
				set { _firstName = value; } }
        [DataMember]
        public string LastName { get { return this._lastName; } 
				set { _lastName = value; } }
        [DataMember]
        public Int32 CustomerID { get { return this._customerID; } 
				set { _customerID = value; } }
    }
}

步骤 2:创建 WF 服务

  1. 右键单击同一解决方案,然后添加一个类型为工作流控制台应用程序的新项目。双击 Workflow1.xaml 进入设计视图。从“Control Flow”拖放“Sequence”到设计窗口的中央。从 Messaging 工具栏部分拖放“ReceiveAndSendReply”到“Sequence”控件的正文上。再次从 Messaging 工具栏拖放同一个 ReceiveAndSendReply 到前面的 ReceiveAndSendReply 下方。

    请参考图片查看 WF 设计(目前,请忽略图片中已更新的操作名称、文本等)。

  2. 单击外部 Sequence 控件。选择左下角的“Variables”,并创建以下变量。在此之前,通过单击解决方案资源管理器中的“添加引用”来引用此控制台应用程序的 Customer(实体库)。
    变量名 变量类型 范围
    __handle 关联句柄 序列
    CurrCustomer 客户 序列

    从下拉列表中,为 __handle 选择 System.ServiceModel.Activities.CorrelationHandle 作为变量类型,同样,为 CurrCustomer 变量选择 Customer.Customer__handle 变量用作句柄,用于将下一个调用路由到已存在的实例,而 CurrCustomer 将保存传递到服务的 Customer 对象的当前状态。

  3. 选择主序列内的第一个 Sequence 控件中的“Receive”活动。在“Receive”活动的属性窗口中执行以下操作。
    OperationName = CreateCustomer 
    ServiceContractName = CustomerService 
    CanCreateInstance = True (Check the check box) 
    CorrelatesWith = __handle 
    CorrelatesOn = From the Xpath Query Dropdown, select Customer ID 
  4. 单击“Receive”框内的“View Parameters”按钮,为该活动从客户端应用程序添加参数。选择“Parameters”单选按钮并输入以下内容
    名称 类型 AssignTo
    value 客户 CurrCustomer

    此步骤将 Customer 对象分配给本地变量 CurrCustomer ,以便在工作流服务中进一步处理。

  5. Receive 和“SendReplyToReceive”控件之间添加“Assign”控件(来自工具栏的 Primitives 部分)。此操作用于在服务中分配任何值。在设计面板中选择此控件后,单击属性窗口中“To”旁边的按钮。您应该能够输入 CurrCustomer.CustomerID 而没有任何错误。如果出现任何错误,会在框的末尾显示一个红色信息图像。单击“确定”并关闭。单击属性框中 Value 旁边的按钮,并输入 New Random().Next()。这将为服务中现有的 Customer 对象分配一个新的 Customer ID (integer))。单击“SendReplyToReceive”框的“View Parameters”按钮并添加以下内容
    名称 类型
    resultAdd 字符串 "Customer Added. ID for " + CurrCustomer.FirstName is " + CurrCustomer.CustomerID.ToString()

    注意:XAML 中要遵循的语法是 VB 语法。因此,我们应该同时学习 C# 和 VB。这个 resultAdd 将作为 string 返回给客户端应用程序。

  6. WriteLine 组件从 Primitives 部分拖放到 SendReplyToReceive 的旁边。这将在服务控制台窗口中打印信息,以便查看服务中发生了什么。
  7. 单击属性窗口中“Text”属性旁边的按钮,然后复制并粘贴以下内容
    "Customer ID Created for " + CurrCustomer.FirstName + " " + 
    	CurrCustomer.LastName + "=" + CurrCustomer.CustomerID.ToString() 

    通过以上步骤,创建已传入 Customer 的 **Customer ID** 的一部分操作已完成。现在,我们将创建另一个 **Receive** 活动来为服务中已存在的 Customer 对象添加姓氏。

  8. 选择设计窗口中的第二个 Sequence,然后单击左下角的 Variables,并添加以下变量
    名称 变量类型 范围
    lName 字符串 序列
    custID Int32 序列
  9. 变量 lName 用于保存从客户端应用程序传入的姓氏值,custID 则用于保存客户 ID。单击 receive 组件的“View Parameters”按钮,并添加以下变量。选择 Parameters 选项按钮。

    名称 类型 AssignTo
    value 字符串 lName
    ID Int32 custID
  10. 选择 Receive 活动,并向相应属性添加以下值
    • OperationName = AddLastName
    • ServiceContractName = CustomerService
    • CorrelatesWith = __handle (这是关联第一个接收和第二个接收活动的部分)
    • CorrelatesOn = 从 Xpath 查询下拉列表中选择“ID : Int32”。这是我们将在客户端应用程序中传递的参数,如上一步所示。

    此时,我们不应该勾选 CanCreateInstance 属性,因为实例已经由第一个 Receive 创建,而从现在开始,我们将更新服务应用程序中已存在的 Customer 对象。

  11. 在设计区域的 ReceiveSendReplyToReceive 部分之间插入 Primitives 部分的 Assign 组件。在 To 文本框中,输入 CurrCustomer.LastName。在 value 文本框中,输入 lName(本地变量名)
  12. 单击 SendReplyToReceive 框中的“View Parameters”按钮,并添加以下内容。选择 parameters 选项按钮。
    名称 类型
    resultAdd 字符串 "last Name " + CurrCustomer.LastName + " added to Customer ID " + CurrCustomer.CustomerID.ToString()

    这是将返回给客户端应用程序的值。

  13. 最后,将 WriteLine 组件拖放到设计区域,并在 Text 属性中输入以下内容,以查看服务中发生了什么。
    "Customer Name :" + CurrCustomer.FirstName + " " + 
    	CurrCustomer.LastName + " ID : " + CurrCustomer.CustomerID.ToString() 

    我们完成了 XAML 中 WF4 服务的创建。

  14. 打开 WF Service App 的 Program.cs 文件,并输入以下内容。
  15. 引用 System.ServiceModel.ActivitiesSystem.ServiceModel.Description 程序集。
  16. 在 main 方法中,复制并粘贴以下内容
    string baseAddress="https://:8081/CustomerService";
    using (WorkflowServiceHost shost = 
    	new WorkflowServiceHost(new Activity1(), new Uri(baseAddress))) 
    { 
        shost.Description.Behaviors.Add(new ServiceMetadataBehavior() 
    	{HttpGetEnabled = true }); 
        shost.Open(); 
        Console.WriteLine("CustomerService is listening @ " + baseAddress); 
        Console.ReadLine(); 
    } 

生成解决方案,并确保没有类型错误或任何其他编译错误。转到 WF Service Console App 的 bin/debug 文件夹并运行该控制台应用程序。

步骤 3:创建客户端应用程序调用 WF 服务

  1. 右键单击解决方案,添加 VC# 控制台应用程序,并将其命名为 ClientApp。将 Customer 库引用添加到项目中。右键单击 ClientApp 的“Service Reference”,然后单击“Add Service reference”。在 Address 栏中键入 https://:8081/CustomerService,然后单击 Go。在 Services 框中,选择服务,然后单击 OK。现在,您已将引用添加到本地运行的服务中。

    注意:每次更改服务后,都需要更新客户端应用程序。

  2. 打开 ClientApp Program.cs 文件,并将以下内容复制并粘贴到 Main 方法中。
    ServiceReference1.CustomerServiceClient csClient = new CustomerServiceClient(); 
    Customer.Customer cust = new Customer.Customer(); 
    string fName; 
    Console.WriteLine("Enter First Name : "); 
    fName =Console.ReadLine(); 
    cust.FirstName = fName; 
    string response = csClient.CreateCustomer(cust); 
    Console.WriteLine(response); 
    Console.ReadLine(); 
    try 
    { 
        Console.WriteLine("Enter last Name : "); 
        cust.LastName = Console.ReadLine(); 
        string response1 = csClient.AddLastName
    			(cust.LastName.ToString(), cust.CustomerID); 
        Console.WriteLine(response1); 
        Console.ReadLine(); 
    } 
    catch (Exception ex) 
    { 
        //Publish the error
    }

好了。您已完成编码。现在,将 ClientApp 设置为启动项目,然后单击 Run 按钮。或者,您可以转到 ClientApp bin/debug 文件夹并执行 EXE。

历史

  • 2010年1月22日:初始发布
© . All rights reserved.