WCF 第十一章 工作流服务 从WF暴露一个服务

开发人员通常使用WF来创建反应程序(reactive program). 程序启动,做一些有用的工作,等待输入,做一些其他有用的工作,等待更多的输入,等等。在一些确定的点,工作流程序结束。反应程序可能运行很长时间,在这个时间内客户端或者服务端的计算机可能关闭。也可能由很多工作流实例的拷贝同时运行,每个实例必须可以独立地寻址以便于它可以接收到外部输入。尽管这些能力对WF来说不是独有的,它们仍然要求特别注意。

  WF设计和运行时环境开发进WCF扩展点来支持这些关键需求。它处理在系统故障时一致的长时间运行的工作流。它将入列消息关联到现有的工作流以便于一个可扩展的宿主可以支持很多运行着的实例。它从工作流程序暴露服务终结点以便于基于标准的消息可以用来通信。

  这一部分以及本章的连续几个部分将介绍WF如何将工作流程序按照服务暴露。我们将通过介绍如何暴露一个简单的工作流来开始。我们将用C#定义一个接口并导入那个接口到WF设计器中。我们将配置一个接收活动来按照一个服务终结点来暴露一个工作流并定义一个请求-回复操作。我们将接下来扩展工作流来使其有多个步骤,其中一个步骤等待外部输入,并为第二个接收活动定义第二个服务操作。我们将介绍一个客户端如何定位并将消息发送给一个特定的运行着的WF实例,最后我们将为工作流添加持久性支持以便于它可以在系统故障时幸存。

定义接口

为了创建一个实现了一个特殊接口的工作流,我们在Visual Studio 中使用顺序工作流服务库模板创建了一个新工程,可以在WCF文件夹下找到。在这个例子中,解决方案和工程都被命名为SimpleService.我们删除了IWorkflow1.cs 和 Workflow1.cs 并定义了一个接口,IStockService, 如列表11.3显示。注意文件中的命名空间是SimpleService.接口的全路径名称为SimpleService.IStockService, 必须被确定为工程中app.config 文件中终结点的契约。

  服务契约有两个操作: InitiateTrade 和 Approval. InitiateTrade 操作处理一个虚拟的货物订单并返回一个TradeRequestStatus 结构的确认号。在一个潜在的欺诈货物订单已经被审查了以后会使用Approval 操作。这个操作被调用来重启一个在等待外部事件的工作流。

  列表11.3显示的接口是工作流服务暴露的接口。相对的,我们可能已经从WF设计器内部为更多的代码的第一个样式定义了接口。通过接口开始,我们可以发布它并与其他开发人员反复交流并最后将它作为开始点来完成服务。或者另外一种方式,以接口开始或者以设计器开始,将产生同样的结果但是契约首先感觉像一个更加深思熟虑的创建服务的方法。

列表11.3 从WF暴露服务接口

namespace SimpleService
{
    [ServiceContract]
	public interface IStockService
	{
        [OperationContract]
        TradeRequestStatus InitiateTrade(TradeRequest tradeRequest);

        [OperationContract]
        void Approval(ApprovalRequest approvalRequest);
	}

    [DataContract]
    public class TradeRequest
    {
        [DataMember] public string account;
        [DataMember] public string action;
        [DataMember] public string ticker;
        [DataMember] public double price;
    }

    [DataContract]
    public class ApprovalRequest
    {
        [DataMember] public string tradeNumber;
        [DataMember] public string approval;
        [DataMember] public string reason;
    }

    [DataContract]
    public class TradeRequestStatus
    {
        [DataMember] public string confirmationNumber;
        [DataMember] public string status;
    }
}

接收活动

一个接收活动将一个操作契约建模。因为列表11.3中有两个操作契约,在工作流上应该有两个接收活动。接收活动的属性是操作契约的输入和返回消息。

  为了实现工作流,我们使用顺序工作流模板(有分开代码)添加一个新的元素。分开代码允许我们查看工作流的XOML表示,这是定义工作流和它的活动的一个XML语法。在WF设计器中打开StockService.xoml文件,在设计界面放一个接收活动,结果如图片11.6显示。

 2011031017165032.png

图片11.6 向工作流设计界面添加一个接收活动

  选择ServiceOperationInfo属性并点击呈现出的一个对话框来选择或者定义一个契约。当你第一次运行这个对话框时,将不会有任何定义的操作契约。点击如图片11.7显示的导入按钮将显示工程和工程所引用的程序集中以[ServiceContract]属性标记的类。仅当那些类中以[OperationContract]标记的方法可以被导入。一个契约定义可以通过对话框直接加入进来,或者你可以选择工程中已有的类定义。我们在工程中引入IStockService 接口就是为了这个目的,结果对话框在图片11.7中显示。注意列出了两个操作,与作为参数使用的负责.NET类型一起。

 2011031017170545.png

图片11.7 为一个接收活动输入或者导入一个接口

  一个WF程序与起任何其他程序相像,所以服务支持一个WF程序通过WCF集成添加所有的WCF功能给其他程序。当一个WCF接收一条消息,它将这条消息反序列化为.NET类型并将这个类型发送给适当的类方法。在一个WF程序内,.NET类型与工作流程序中的一个本地变量关联。

  操作契约中定义的每个参数必须绑定到一个WF字段或者属性。提供一个对话框来帮助你选择将一个已有变量(字段或者属性)或者创建一个新的变量来绑定到参数。当你在接收活动属性节一个参数名的旁边点击忽略时会弹出一个对话框。图片11.8显示绑定工作流变量到操作契约参数的对话框。

 2011031017171468.png

图片11.8 绑定操作契约参数到工作流变量

  在这个时候服务接口已经完全定义好了。服务还没有做任何事情,但是它的接口已经定义好了。下一步就是更新接收活动来包含一个代码活动并发送一个有意义的反馈给客户端。我们将稍后在这一章实现Approval(批准)代码. 在这个例子中,代码设置操作契约的返回值为一些看来是一个确认号码的文字。注意一个接收活动是一个合成活动,所以你可以在接收活动中加入任何活动而且它将在回复消息发回给客户端后执行。通过保持接收活动内部的代码到一个最小值,服务操作将向客户端传递更快的性能。

  工作流最后的配置在图片11.9显示。注意InitiateTrade返回值和输入参数绑定到变量。也要之一CanCreateInstance 属性被设置为true.这说明宿主环境当接收一条没有与其他实例挂念的消息时会将其绑定到WF运行时内部的一个新实例。

 2011031017172425.png

图片11.9 工作流暴露一个接收活动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值