VS2008 WorkFlow使用自定义活动添加工作流逻辑

上面介绍了采用CodeActivity来定义工作流。而我们现在来看看另一种向工作流中添加代码的方法——使用自定义活动。我们还是使用前面用到的下单的例子,看看两者有何不同。

 

采用自定义活动的好处就在于我们开发的代码段是离散、可分离、可复用的组件。一旦测试成功,我们就可以采用拖放的方法将其添加到任意的工作流中。而CodeActivity的复用仅仅限于在当前的工作流中。

 

定义Custom Activities

OK,下面开始动手。建立一个名为OrderEntryActivitiesSequential Workflow Console Application工程,然后从Project菜单中选择Add Activity,添加名为ValidateAccountActivityActivity。一般来说,命名的时候以Activity来结尾,比较规范。

 

进入ValidateAccountActivity.cs的代码,把它的基类由SequenceActivity改为Activity,因为这是一个单一的活动,没有必要采用Sequence

 

每个自定义的活动都应该设计为独立的组件,它们有自己的输入和输出参数。一个活动并不知道工作流中其它活动的任何信息,只能通过属性值来进行通讯。为了支持绑定,我们采用从属属性(dependency properties)代替常规的.NET属性。此活动所需的从属属性有下面几个:

 

l  AccountIdint型,标识待验证的帐号;

l  IsAccountVerifiedbool型,指示AccountId是否有效;

l  AvailableCreditdecimal型,包含有帐户的信用卡余额

 

下面的代码就是添加了从属属性之后的ValidateAccountActivity.cs文件。记着在这里可以使用CodeSnippet来快速插入代码。

 

using System;

using System.ComponentModel;

using System.ComponentModel.Design;

using System.Collections;

using System.Drawing;

using System.Workflow.ComponentModel;

using System.Workflow.ComponentModel.Design;

using System.Workflow.ComponentModel.Compiler;

using System.Workflow.ComponentModel.Serialization;

using System.Workflow.Runtime;

using System.Workflow.Activities;

using System.Workflow.Activities.Rules;

 

namespace OrderEntryActivities

{

     public partial class ValidateAccountActivity: Activity

     {

         public ValidateAccountActivity()

         {

              InitializeComponent();

         }

 

        #region Public workflow properties

       

        public static DependencyProperty AccountIdProperty = DependencyProperty.Register("AccountId", typeof(int), typeof(ValidateAccountActivity));

 

        [DescriptionAttribute("AccountId")]

        [CategoryAttribute("AccountId Category")]

        [BrowsableAttribute(true)]

        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]

        public int AccountId

        {

            get

            {

                return ((int)(base.GetValue(ValidateAccountActivity.AccountIdProperty)));

            }

            set

            {

                base.SetValue(ValidateAccountActivity.AccountIdProperty, value);

            }

        }

 

        public static DependencyProperty AvailableCreditProperty = DependencyProperty.Register("AvailableCredit", typeof(int), typeof(ValidateAccountActivity));

 

        [DescriptionAttribute("AvailableCredit")]

        [CategoryAttribute("AvailableCredit Category")]

        [BrowsableAttribute(true)]

        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]

        public int AvailableCredit

        {

            get

            {

                return ((int)(base.GetValue(ValidateAccountActivity.AvailableCreditProperty)));

            }

            set

            {

                base.SetValue(ValidateAccountActivity.AvailableCreditProperty, value);

            }

        }

 

        public static DependencyProperty IsAccountVerifiedProperty = DependencyProperty.Register("IsAccountVerified", typeof(bool), typeof(ValidateAccountActivity));

 

        [DescriptionAttribute("IsAccountVerified")]

        [CategoryAttribute("IsAccountVerified Category")]

        [BrowsableAttribute(true)]

        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]

        public bool IsAccountVerified

        {

            get

            {

                return ((bool)(base.GetValue(ValidateAccountActivity.IsAccountVerifiedProperty)));

            }

            set

            {

                base.SetValue(ValidateAccountActivity.IsAccountVerifiedProperty, value);

            }

        }

        #endregion

    }

}

 

属性添加完毕,我们需要实现活动的逻辑。实际执行的逻辑是存放在Execute方法中的。这个方法是由基类提供的虚方法,在我们这个派生类中必须要重载实现。当活动被执行时,这个方法就会被工作流运行时同步调用。模拟查找和验证用户的代码如下所示:

 

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

    {

        switch (AccountId)

        {

            case 1001:

                IsAccountVerified = true;

                AvailableCredit = 100.00M;

                break;

            case 2002:

                IsAccountVerified = true;

                AvailableCredit = 500.00M;

                break;

            default:

                IsAccountVerified = false;

                AvailableCredit = 0;

                break;

        }

 

        return base.Execute(executionContext);

    }

 

同样的道理,我们继续添加商品验证活动ValidateProductActivity以及下单活动EnterOrderActivity,具体实现参见源码。

 

现在进入我们最终承载功能的工作流Workflow1.cs代码,首先还是添加从属属性,AccountIdSalesItemId,参见源码。在这个文件中,我们上一种方法里需要添加的私有字段就不复存在了。代码完成之后,请按下F6编译整个工程文件。

 

切换到设计模式,可以看到在Toolbox中已经有我们自定义的活动了(如果没有,请编译一下工程),如下图所示:

 



 

绘制工作流

拖放一个ValidateAccountActivity的实例到工作流中。我们现在需要把该活动的AccountId属性与工作流的对应属性绑定起来。要达到这个目的,切换到该活动的属性窗口,如图:

 



现在绑定AccountId属性,点击它后面的省略号,打开一个如下所示的绑定对话框。

 



在这个对话框中,我们可以把工作流或者是别的活动的属性绑定到此活动的属性上。只有从属属性才能实现这种功能。在这个例子中,我们将此活动的AccountId属性绑定到工作流的AccountId上。在运行时,通过Dictionary传递给工作流的属性值也会自动地传递到这个活动来。在这个列表里选中AccountId,点击确定。属性窗口中的另外两个属性,AvailableCreditIsAccountVerified是活动的输出,现在暂时不需要设置绑定。

 

现在拖放一个IfEElseActivity到刚才那个活动的下方。这个分支活动将根据validateAccountActivity1IsAccountVerified属性来确定工作流的走向。左边的分支代表着帐户有效,右侧代表无效。分别将它们重新命名为ifAccountVerifiedifAccountInvalid

 

在属性窗口里,设置一个this.validateAccountActivity1.IsAccountVerified==trueDeclarative Rule Condition,具体做法就不赘述了。

 

补完右侧的分支,拖放一个CodeActivity,添加如下代码:

 

    private void codeBadAccountId_ExecuteCode(object sender, EventArgs e)

    {

        Console.WriteLine("AccountId {0} 无效", AccountId);

    }

 

同样的方法,我们继续往下去补充验证商品以及下单的工作流逻辑。请参阅我提供的源码示例。就在今天,.NET Framework 3.5发布了正式版,经过我的测试,卸载beta2版的Framework 3.5,再安装正式版的之后,VS2008 beta2仍然可以正常运行。现在的示例统统都是在正式版的Framework 3.5下编译测试通过的。

 

最后完成之后的工作流看起来应该是下面的样子:

 



然后就是修改Program.cs文件,调用这个工作流了。大部分都可以从上一个示例里照抄,唯一需要改动的就是下面的加粗部分:

 

    public void RunWorkflow(Dictionary<string, object> wfArguments)

    {

        // 创建工作流实例并启动

        WorkflowInstance instance = _workflowRuntime.CreateWorkflow(typeof(OrderEntryActivities.Workflow1), wfArguments);

        instance.Start();

 

        // 等待工作流完成

        _waitHandle.WaitOne();

    }

 

好,F5编译执行,如果一切正常的话,结果应与上一节里看到的完全相同。

转载于:https://www.cnblogs.com/viki117/archive/2008/02/27/1083502.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值