在第四章,你建立了一个工作里计算订单的总费用。在这一章,你将添加逻辑去添加每一个订单项的费用。
复用第四章的项目
打开Visual Studio 2010,创建一个新的项目。选择一个Blank Solution模板,如图Figure5-1所示。输入解决方案名为Chapter05。
然后,复制Chapter04的文件夹到Chapter05的文件夹,如图Figure5-2所示。
在Solution Explorer中,右击Chapter05解决方案,选择Add>Existing Project,如图Figure5-3所示。
添加现有项目的对话框如图Figure5-4所示。在目录Chapter05\OrderProcess中选择OrderProcess.csproj文件。
当你点击Open按钮的时候,OrderProcess就会加载到解决方案中,Solution Explorer应该如图Figure5-5所示。
添加OrderItem处理
现在你将添加一些步骤去计算订单项的费用。
ForEach活动
ForEach活动对集合中的每一项都执行一个或一系列活动。这正是项目所需要的。
打开OrderWF.xaml文件(设计视图)。拖放一个ForEach<T>活动在“Initialize Total”活动下面。修改DisplayName为Accumulate Order Items。这个活动是处于收缩状态的,点击活动的右上角的展开按钮,活动会如图Figure5-6所示。
在Expression中输入:
OrderInfo.Items
活动中的<T>表明他是一个泛型类,你可以定义在集合中的类型。在Properties(属性)窗口,你可以看见默认类型为Int32。你可能已经注意到出现了一个红色的圆圈表明有一个错误(如图Figure5-7所示)。这表明在Expression中,你输入的OrderInfo.Items,没有包含一个整型的集合。
OrderInfo.Items是一个OrderItem对象的集合。在TypeArgument的下拉列表中选择Browse for Types。在弹出的对话框中展开OrdeProcess引用,选择OrderItem类,如图Figure5-8所示。
对于这个项目,你将简单的对所有项收取固定的费用,你可以从数据库中读取项的信息。拖拉一个Assign活动到ForEach活动中。
提示你只可以拖放一个活动到ForEach活动中,如果你需要多个活动,你先可以拖放一个Sequence活动,然后再添加活动到Sequence活动中。
对于To属性,输入TotalAmount;在Value属性输入以下代码:
TotalAmount + (item.Quantity * 10.0D)
这时工作流图如图Figure5-9所示。
拖放一个WriteLine活动到“Accumulate Order Items”下面。DisplayName为Display Item Total,Text属性为:
“The item total is: $” + TotalAmount.ToString()
这会展示在添加总费用之前订单项的总和。完整的工作流图如图Figure5-10所示。
提示:我点击了Collapse All Link按钮(在工作流设计器的右上角),所示现在看到的是整个工作流图,注意到“Accumulate Order Items”和“Handling Charges”活动有一个Expand link在右上角。你可以点击这些链接去展开每一个活动。
添加Order Items
在你测试之前,你需要修改应用程序,添加一些OrderItem对象到Order类中。打开Program.cs文件,添加以下代码在Order类创建之后:
//Add some OrderItem object
myOrder.Items.Add(new OrderItem
{
OrderItemID = 1,
Quantity = 1,
ItemCode = "12345",
Description = "Wight"
});
myOrder.Items.Add(new OrderItem
{
OrderItemID = 2,
Quantity = 3,
ItemCode = "12346",
Description = "Gadget"
});
myOrder.Items.Add(new OrderItem
{
OrderItemID = 3,
Quantity = 2,
ItemCode = "12347",
Description = "Super Wight"
});
运行程序
点击F5运行程序。结果应该如下:
第一个OrderItem的quantity为1,第二个为3,第三个为2。因此一共六项,每项$10,一共$60。在上一章中,费用也是$60。因此一共为$120。
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
};
//Add some OrderItem object
myOrder.Items.Add(new OrderItem
{
OrderItemID = 1,
Quantity = 1,
ItemCode = "12345",
Description = "Wight"
});
myOrder.Items.Add(new OrderItem
{
OrderItemID = 2,
Quantity = 3,
ItemCode = "12346",
Description = "Gadget"
});
myOrder.Items.Add(new OrderItem
{
OrderItemID = 3,
Quantity = 2,
ItemCode = "12347",
Description = "Super Wight"
});
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();
}
}
}
ParallelForEach活动
除了ForEach活动,你也可以使用ParallelForEach活动,它们有很多相同点,但有一点不同,就是循环体是怎么执行的。
正如它的名字,ParallelForEach活动的子活动是同时执行的,而ForEach活动是顺序的执行的。对于这个项目,这两个活动的使用是没有区别的。但对于更复杂的活动序列,同时运行它们可能更好。例如,你发一条信息,然后等待回复,你可以同时的运行这两个活动,这样在等待的过程中,你就可以做其他事情了。
为了去测试一下,你可以删除ForEach活动,然后拖放一个ParallelForEach活动到它原来的位置上。跟ForEach的配置一样,然后运行程序,你会得到同样的结果。