在第一章,我已经向你展示了在工作流中怎么使用variables(变量)和arguments(参数)。跟编码类似,variables类似于类成员,而arguments类似于方法的参数。你已经在前三章使用过variables了,在这一章,我将向你展示怎样使用input(输入)、output(输出)arguments(参数)和arguments(参数)是怎么在workflow和宿主程序之间传递。

创建一个新的解决方案

创建一个新的Workflow Console Application,如图Figure4-1。命名这个项目为OrderProcess,同时命名这个解决方案为Chapter04。

在这个项目中,你将定义一个货物订单,然后把订单传递到工作流中。工作流将会计算订单的费用,然后把费用返回给应用程序。

定义订单类

第一步是定义订单的数据类型。在Solution Explorer(解决方案)中右击项目,选择Add > Class,如图Figure4-2所示。

在Add New Item对话框中(如图Figure4-3),选择Class模板(它应该已经被默认地选择了),指定它的名字为Order.cs,点击Add。

Solution Explorer(解决方案窗口)应该如图Figure4-4所示。

在Order类中输入以下代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace OrderProcess

{

    public class OrderItem

    {

        public int OrderItemID { get; set; }

        public int Quantity { get; set; }

        public string ItemCode { get; set; }

        public string Description { get; set; }

    }

 

    public class Order

    {

        public Order()

        {

            Items = new List<OrderItem>();

        }

 

        public int OrderID { get; set; }

        public string Description { get; set; }

        public decimal TotalWeight { get; set; }

        public string ShippingMethod { get; set; }

 

        public List<OrderItem> Items { get; set; }

    }

}

Order类包含了一些公有成员(OrderID,Description,TotalWeight,ShippingMethod)和一个OrderItem类的集合。工作流会根据这些内容区决定订单的金额。点击F6去生成解决方案。这会编译生成Order类,后面我们需要用到。

实现工作流

模板为我们创建了一个工作流文件,名叫Workflow1.xaml。在Solution Explorer中,右击Workflow1.xaml文件,选择Rename(重命名),如图Figure4-5所示。命名为OrderWF.xaml。

你同样要打开OrderWF.xaml的code view。在第一行,修改Class属性为:

x:Class="OrderProcess.OrderWF"

定义Arguments

打开OrderWF.xaml文件(design(设计)视图)。现在定义输入输出arguments。点击工作流设计器的左下角的Argument按钮。设计器将会弹出以下窗口(如图Figure4-6)。

提示:你可能会想起第一章中定义variables时是需要指定范围的,范围可能是整个工作流或者是特定的一个活动(和他的子活动)。对于arguments,然而,是不需要定义范围的,因为它已经被默认的指定为对整个工作流有效,因为它是指定来传入传出数据到工作流的。因此,当定义argument是是没有Scope属性的。

点击Create Argument链接。输入Name为OrderInfo。Direction为In。点击ArgumentType,将会弹出一个下拉菜单,如图Figure4-7所示。

选择最后一条(Browse for Types)。这时会弹出一个对话框,如图Figure4-8所示。

展开OrderProcess引用,选择Order类,点击OK。

提示:如果在OrderProcess引用中看不见Order类,你必须生成解决方案。点击Cancel按钮,点击F6生成解决方案(这时有可能报错“The type or namespace name ‘Workflow1’ could not be found (are you missing a using directive or an assembly reference?)”)

,然后就可以设置Argument类型了。

再次点击Create Argument链接,创建另外一个argument。输入Name为TotalAmount,Direction为Out,ArgumentType为Decimal。Decimal类型不再下拉列表中,你需要导航到这个类型(正如第一个argument定义那样)。Decimal类型可以在mscorlib引用的System命名空间中找到。

提示:你不必通过浏览引用和命名空间来找你需要的类型。你可以直接在对话框的最上面输入类型的命名空间和类型。例如,需要Decimal类型,只是需要输入System.Decimal。实际上,你甚至不需要输入特定的命名空间,你只要输入Decimal,之后下面就会出现匹配的类型。

设计工作流

现在你可以设计活动来处理传进来的订单了。首先拖拉一个Sequence活动到工作流设计器上,然后拖放一个WriteLine活动到Sequence中。设置Text属性为“Order Received”。拖放一个Assign活动到WriteLine活动的下面。设置DisplayName为Initialize Total。To属性为TotalAmount,Value属性为0。Assign的属性窗口如图Figure4-9所示。

这个活动简单的把TotalAmount初始化为0。

Switch活动

Switch活动的工作原理跟C#中的switch类似。它允许你执行一系列的活动根据表达式的值。你将会使用Switch活动去验证ShippingMethod而去决定收费。在Toolbox中,Switch活动显示为Switch<T>。这意味着他是一个模板类和他可以操作不同的数据类型。拖放一个Switch活动到Assign活动的下面。你应该可以看到弹出了一个对话框,如图Figure4-10所示,这个对话框要求你指定数据类型。ShippingMethod是一个string类型,因此选择String类型。

点击OK。在属性窗口中,设置DisplayName为Handling Charges。Handling Charges活动应该如图Figure4-11所示。

Switch活动有一个Expression属性,一个default分支,和一些用户定义的分支。输入expression为OrderInfo.ShippingMethod。点击Add new case链接(在活动的底部)。输入case的值为NextDay。再次点击Add new case,输入case为2ndDay。这时活动如图Figure4-12所示。

设计器显示了所有的case(分支),和其中一个分支是展开的,以便你可以看到这个分支中有哪些活动。你可以点击Add an activity链接展开一个收缩的分支。

Expression活动

到目前为止,你已经定义了NextDay和2ndDay分支到Switch活动中,default分支是用来当ShippingMethod不是其中一个分支的值时来执行的。现在你需要指定每一个分支要执行的活动。对于这个项目,你将使用Add活动。

提示:在System.Activities.Expressions命名空间中包含了很多工作流活动。包括Add,Subtract,Multiply和Divide活动。它也包括Equal,GreaterThan,And和Or活动,你可以直接在你的工作流中使用它们。

不幸运的是,Add活动不能在toolbox中,你需要直接在.xaml代码中输入这个活动。保存项目。在Solution Explorer中右击OrderWF.xaml,选择View Code。它会弹出一个窗口询问你是否关闭现有窗口,点击Yes。Switch活动定义如下:

<Switch x:TypeArguments="x:String" DisplayName="Handling Charges" Expression="[OrderInfo.ShippingMethod]" sap:VirtualizedContainerService.HintSize="481,260">

<x:Null x:Key="NextDay" />

<x:Null x:Key="2ndDay" />

</Switch>

注意到NextDay和2ndDay分支的属性x:Null,这表明这个分支没有包含活动,用以下代码覆盖这两行代码:

<Add x:TypeArguments="x:Decimal, x:Decimal, x:Decimal" x:Key="NextDay" sap:VirtualizedContainerService.HintSize="461,100" Left="[TotalAmount]" Result="[TotalAmount]" Right="[15]" />

<Add x:TypeArguments="x:Decimal, x:Decimal, x:Decimal" x:Key="2ndDay" sap:VirtualizedContainerService.HintSize="461,100" Left="[TotalAmount]" Result="[TotalAmount]" Right="[10]" />

在上面代码之前加上:

<Switch.Default>

<Add x:TypeArguments="x:Decimal, x:Decimal, x:Decimal" sap:VirtualizedContainerService.HintSize="463,100" Left="[TotalAmount]" Result="[TotalAmount]" Right="[5]" />

</Switch.Default>

注意:以上代码跟原文有不一致,因为我试过原文的方法会报错,所以我直接把Add活动添加到toolbox中,然后拖放到相应的分支中,上面的代码是自动生成的。

Add活动有三个属性:Left,Right和Result。Right的值加上Left的值然后赋值给Result属性,Left和Result属性设置为TotalAmount参数,Right属性被指定为一个常数。

Switch活动的完整定义如下:

<Switch x:TypeArguments="x:String" DisplayName="Handling Charges" Expression="[OrderInfo.ShippingMethod]" sap:VirtualizedContainerService.HintSize="481,258">

<Switch.Default>

<Add x:TypeArguments="x:Decimal, x:Decimal, x:Decimal" sap:VirtualizedContainerService.HintSize="463,100" Left="[TotalAmount]" Result="[TotalAmount]" Right="[5]" />

</Switch.Default>

<Add x:TypeArguments="x:Decimal, x:Decimal, x:Decimal" x:Key="NextDay" sap:VirtualizedContainerService.HintSize="461,100" Left="[TotalAmount]" Result="[TotalAmount]" Right="[15]" />

<Add x:TypeArguments="x:Decimal, x:Decimal, x:Decimal" x:Key="2ndDay" sap:VirtualizedContainerService.HintSize="461,100" Left="[TotalAmount]" Result="[TotalAmount]" Right="[10]" />

</Switch>

保存项目,右击OrderWF.xaml文件,选择View Designer,Switch活动如图Figure4-13所示。

当ShippingMethod为NextDay是,TotalAmount将会增加15$;当为2ndDay是,将增加10$。当为其他值时,将增加5$。如果你点击其中的一个switch分支,你将看到分支中包含什么活动,如图Figure4-14所示。

点击Add活动,它的属性将在属性窗口出现(如图Figure4-15所示),如果需要,你可以在这里直接修改它的属性。

拖放另外一个Assign活动到Switch活动的下面,DisplayName为Freight Charges。To属性为TotalAmount,Value属性为:

TotalAmount + (OrderInfo.TotalWeight * 0.50D)

拖放一个WriteLine活动到“Freight Charges”活动的下面,设置Text属性为:

“That Total amount is: $” + TotalAmount.ToString()

这展示了订单的总金额。最后的工作流图应该如图Figure4-16所示。

引用工作流

在这个项目,控制台程序自动的引用了工作流,用下面代码覆盖Program.cs:

using System;

using System.Linq;

using System.Activities;

using System.Activities.Statements;

using System.Collections.Generic;

 

namespace OrderProcess

{

 

    class Program

    {

        static void Main(string[] args)

        {

            Order myOrder = new Order()

            {

                OrderID = 1,

                Description = "Need some stuff",

                ShippingMethod = "2ndDay",

                TotalWeight = 100

            };

 

            IDictionary<string, object> input = new Dictionary<string, object>

            {

                {"OrderInfo", myOrder}

            };

 

            //execute the workflow

            IDictionary<string,object> output = WorkflowInvoker.Invoke(new OrderWF(), input);

 

            //Get the TotalAmount returned by workflow

            decimal total = (decimal)output["TotalAmount"];

            Console.WriteLine("Workflow return ${0} for my order total", total);

 

            Console.WriteLine("Press ENTER to exit");

            Console.ReadLine();

        }

    }

}

首先创建了一个Order对象,在Order对象中定义了测试的数据。然后创建了一个Dictionary对象,用来存储Order对象。调用了WorkflowInvoker类的静态方法Invoke(),在Invoke()方法中传递了Dictionary对象。Invoke()方法创建和执行一个工作流实例在应用程序的线程中。

在Dictionary中传递数据是可以同时传多个参数的。这是非常重要的去匹配dictionary的key和工作流中的传入参数,而且dictionary中对象的类型也要与工作流中传入参数匹配。

Invoke()方法返回一个Dictionary对象,这个dictionary对象包含了工作流的所有传出和传出/传入参数。

运行程序

点击F5运行程序,结果应该如下所示:

为了去验证结果是否正确,你可以手动的去计算一下。ShippingMethod是2ndDay,这代表要加上$10。TotalWeight为100,价格为$0.50一磅,这就是一共$50。加上前面的$10就是$60。

第四章源码下载

转载于:https://www.cnblogs.com/kukafeiso/archive/2010/06/18/1760048.html

Beginning WF 4.0翻译——第四章(传递参数)相关推荐

  1. 转载:Beginning WF 4.0翻译——第四章(传递参数)

    在第一章,我已经向你展示了在工作流中怎么使用variables(变量)和arguments(参数).跟编码类似,variables类似于类成员,而arguments类似于方法的参数.你已经在前三章使用 ...

  2. 《Undocumented Windows 2000 Secrets》翻译 --- 第四章(6)

    第四章  探索Windows 2000的内存管理机制 翻译:Kendiv( fcczj@263.net ) 更新:Sunday, February 17, 2005 声明:转载请注明出处,并保证文章的 ...

  3. 《Fundamentals of Computer Grahpics》虎书第三版翻译——第四章 光线追踪

    光线追踪 计算机图形学的基本任务之一是绘制三维物体:获取一个场景或模型(由许多在3D空间中排列的几何物体组成),并生成一个二维图像(从一个特定的视角观察到的物体的图像).这和几个世纪以来建筑师和工程师 ...

  4. 极验验证码(6.0.9)破解(四) 之 'aa' 参数调试和分析

    回顾 上篇文章 介绍了'userresponse' 参数调试和分析,并将js执行过程整理出来,整理成python代码. 今天我们继续进行极验破解,这次我们介绍 'aa'参数的生成,距离上篇文章,已经过 ...

  5. bat批处理(二):%0 %1——给批处理脚本传递参数

    初次接触批处理脚本觉得有点意思,所以决定写一个小功能试验一下,谁知刚一开始就发现遇到了麻烦,本想着使用参数来控制程序的运行结果,可是参数怎么传进去呢,于是研究了一番,最终发现这个参数的传递与main函 ...

  6. JSP中四种传递参数的方法

    1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="index.jsp"?a= ...

  7. 谭浩强《C++程序设计》书后习题 第十三章-第十四章

    2019独角兽企业重金招聘Python工程师标准>>> 最近要复习一下C和C++的基础知识,于是计划把之前学过的谭浩强的<C程序设计>和<C++程序设计>习题 ...

  8. 第十四章_超参数调整

    文章目录 14.1 写在前面 14.2 超参数概述 14.2.1 什么是超参数,参数和超参数的区别 14.2.2 神经网络中包含哪些超参数 14.2.3 模型优化寻找最优解和正则项之间的关系 14.2 ...

  9. Gradle 1.12用户指南翻译——第五十四章. 构建原生二进制文件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

最新文章

  1. 《ArcGIS Runtime SDK for Android开发笔记》——数据制作篇:发布具有同步能力的FeatureService服务...
  2. 【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用父类方法 | 静态多态 | 动态多态 | 虚函数 | 纯虚函数 )
  3. 你发这些什么目的_吸引女生冷知识:朋友圈发照片的“潜规则”,男生要懂
  4. bzoj1597[Usaco2008 Mar]土地购买
  5. 攻击 | 破解windows7密码(利用PE系统破解XP密码)
  6. rabbitmq3.7.3 发布了一个新的 exchange x-random
  7. 大淘客cms源码修改二次开发实现淘京拼三合一功能
  8. 微信公众账号登陆授权开发——2
  9. Spring| AOP之 引入(Introductions)
  10. PD虚拟机如何设置内存和CPU核心数
  11. 电感耦合等离子体光源(ICP)
  12. 云服务器和普通服务器主要区别有三点
  13. uniapp开发抖音小程序注意事项
  14. CUDA流多处理器(stream multiprocessor,sm)和硬件流处理器(stream processor,sp)
  15. python-opencv截取视频片段
  16. Note For Linux By Jes(16)-软件安装:原始码与 Tarball
  17. 竞斗云2.0刷机-编程器刷入opboot
  18. 英伟达 linux 官方驱动 双显卡,反复几次:今天终于弄好双显卡驱动了!
  19. 基于Dragonboard 410c 的Grove - Digital Light Sensor驱动移植
  20. 前端工程化系列[01]-Bower包管理工具的使用

热门文章

  1. 如何寻找互联网红利期产品?
  2. 计算机网络之传输介质(双绞线、同轴电缆、光纤、无线电缆、微波、激光、红外线)...
  3. 火狐浏览器使用copper插件无反应问题
  4. python 中 print 函数用法总结
  5. jdbc数据源连接oracle,请教JDBC怎么连接ORACLE数据库
  6. azure db 设置时区_关于Azure Cosmos DB(以前称为DocumentDB)的8件事
  7. azure模型训练_如何在Azure Machine Learning Studio上开发K-Means模型
  8. sql server父节点_将新节点添加到现有SQL Server Always On可用性组中
  9. 逻辑数据库设计 - 单纯的树(邻接表、路径枚举、嵌套集、闭包表)(引)
  10. UK Biobank专题