代码改变世界

《WF编程》系列之35 - 自定义活动:为何创建自定义活动?

2007-11-25 23:58  Windie Chai  阅读(2867)  评论(0编辑  收藏  举报

5 自定义活动

使用通用的framework来开发软件虽然轻松,但却不够高效.我们每天都会遇到一些问题,只有使用专门面向这些问题的framework来开发软件才是真正的轻松并且高效.通过自定义活动,我们可以为这些日常问题量身打造工作流.自定义活动可以用来解决特定业务领域的问题,譬如,医疗软件中化验病人的血液样本的过程;我们也可以为IT领域编写自定义活动.如果我们的应用程序大量使用了Microsoft Message Queuing(MSMQ),我们就可以创建和MSMQ交互的自定义活动.
这一章将会讲述如何编写自定义活动,并且深入研究实现自定义活动的不同方式.我们会讨论如何使用组合的方式创建黑盒活动和白盒活动;如何使用继承的方式来创建自定义活动;如何创建验证和设计时的行为.接着,我们还会讨论一些相关概念,比如依赖性属性(Dependency Property)和执行上下文(Execution Context).在本章的最后,我们将比较组合和继承这两种创建自定义活动方式,并理解创建自定义活动的要点.

5.1 为何创建自定义活动?

有很多创建自定义活动的动机,其中三个可能的动机是:
 创建可重用的组件
 扩展Windows Workflow
 创建针对特定领域的工作流

5.1.1 复用性

作为开发人员,我们不喜欢五行一模一样的代码在应用程序中多次出现,我们会选择将这些可以重用的代码封装到一个方法里;同样,无论在ASP.NET还是Windows Form应用程序中,我们都不希望多个窗体中包含五个相同的控件,我们会编写自定义控件,并在多个窗体中重用这些控件.需要改变时,我们只需要更改一处便可以让其它位置全部更改,无论这一处被多少个应用程序使用.那么我们如何在Windows Workflow中重用逻辑和代码呢?答案就是自定义活动.
在Windows Workflow中,有一种创建自定义活动的方法-组合.我们可以用现成的活动来组成自定义活动.我们可以将这些活动封装到活动库中,然后在多个工作流中重用.简单的说,组合的目的就是重用.

5.1.2 扩展性

基本活动库中的活动无外乎两类:一种用来控制流,一种用来以确定的语义执行工作流.而且并没有什么特别之处-它们没有使用隐藏的API,WF Runtime也不会以不同的方式执行这些预置活动和我们的自定义活动.
如果一个工作流不适应我们的需求,我们可以依照我们的需求重新设计.同样,如果While和IfElse活动不够灵活,我们也可以编写我们自己的控制流的活动,比如ForEach活动.扩展性就是创建基本活动库之外的新的活动.

5.1.3 领域特定语言 DOMAIN-SPECIFIC LANGUAGES

医生的财务软件使用了术语charges和receipts.银行的财务软件使用了术语debits和credits.虽然这两个软件都用来管理资金的流入和流出,但如果交换了它们的位置,我们仍然可以分辨出来它们真正的用武之地.原因很简单,因为它们使用了不同的术语.这就是领域特定语言(DSL)的好处,一种使用解决问题的标准词汇来表达解决方案的能力.
而且,标准术语的优势不仅仅体现在上述的例子中.领域特定语言允许我们将工作高度抽象化.例如,文档管理解决方案中的一个普通的任务-文档审批.如果开发人员编写了一个文档审批的工作流,他会在适当的位置添加并配置HandleExternalEvent活动来等待审批事件.HandleExternalEvent是一个通用的活动,可以处理任何类型的事件,并且它需要接口,类型和事件处理程序等相关知识来设置属性.
而另一方面,我们的开发人员也可以实现一个名为WaitForDocumentApproval自定义活动.除了使用文档管理领域的原生术语之外,自定义活动还可以预先配置好相应的事件处理程序.所以活动干脆屏蔽了工作流设计器中指定接口和类型的部分.高度抽象化的好处就是高效.