简介
通过使用wwf,你可以创建基于处理器流的工作流并且把它们部署在任何类型的.net应用程序中。此外,本文还讨论了asp.net开发者面对的一些特有的问题-这些问题可能通过使用工作流得到解决,如维持状态和页面导航等。
在2005年9月,微软在它的一年两次的专业开发者会议上公开了windows workflow foundation(wwf,windows工作流基础)。作为winfx api的支柱之一,wwf提供给开发者一个普通框架-在其上开发过程驱动的和以工作流为中心的应用程序。
当前,有些组织力图把整个商业过程自动化;他们的标准答案就是集合一队开发者来开发相应的代码。尽管这种方式对于这些组织带来良好的作用,然而也有一些固有的问题。为了深入理解这一问题,你需要理解一个工作流的基本特征。
一个工作流本质是一种方法-用来归档包含在完成一个单元的工作中的活动。典型地,在处理过程中,工作”流”流过一项或更多活动。这些活动可以通过机器或人工来实现,并且有可能象在一个互联网应用程序定义页面顺序一样得简单,也有可能象管理必须为任何数目的人都要看到、更改并同意的文件或产品一样得复杂。
因为如此多的工作流必须考虑到人工参预,所以可能需要花费很长工期才能完成,时间可能为几小时到数月或更长。例如,参预在该过程中的人可能无法找到,不在本地或忙于另外的任务;因此,工作流必须在所有非活动期间能够把自身持续性存储。而且,通过编码独立实现的过程可能对非技术人员难于理解而对开发者却难于更改。这一点和其它一些因素正是例如windowswf等通用工作流框架的目标-其目的就在于使创建、改变和管理工作流更容易-这是通过向它们提供一个可视化接口或通过定义一组普通api来实现的。
你可以把wwf工作流放置在任何类型的.net应用程序中-包括windows表单程序,控制台应用程序,windows服务和asp.net web应用程序。每种类型都需要专门的考虑。尽管一些现有示例已经足够说明如何把工作流宿主到windows表单程序和控制台应用程序中,但是本文将集中于讨论asp.net开发者的问题-他们希望把工作流集成到自己的应用程序中。
作者注:本文所提供的代码是以windows wf beta 1和visual studio 2005 beta 2 为工具创建的。你可以在www.windowsworkflow.net找到有关安装windows wf的信息。尽管本文讨论了windows wf的一些基础问题,但是还有其它一些这方面的可用资源。我假定读者至少了解一点windows wf。本文的目的是深度分析windows wf和asp.net,而不是从一个高层次上讨论windows wf。
一、 windows wf和mvc模式
在开发一个asp.net应用程序时,你可能使用wwf的一个普通的方法是实现一种模型-视图-控制器(mvc)方法。实质上,mvc的目标是把描述层、应用程序逻辑和应用程序流逻辑分离开来。
搞清楚这个将十分有益于一个asp.net应用程序的开发,请考虑一个帮助桌面票工作流的场所。假定有一个商业用户通过填写一个asp.net web表单并点击一个提交按钮来启动该工作流。接下来,服务器就会通知一个使用windows表单应用程序和帮助桌面的雇员–“有新票可用了”。该帮助桌面雇员然后将在这一问题上工作,并在最后关闭该票。如果使用windows wf来开发这个工作流情形,那么所有的处理逻辑和流程可以被包含在工作流本身,而该asp.net应用程序将完全不需要了解这一逻辑。
这种场所提供了一些稳固的证据-把描述与逻辑相分离是一件好事情。因为这个处理帮助桌面请求的过程是非常普通的,如果使用c#或vb.net代码在若干不同的.net应用程序中实现这一逻辑,那么你将会冒着重复编码的危险甚至更坏的情形–用完全不同的代码导致同样的商业处理过程的不同实现。但是如果你使用wwf来实现这一过程,那么需要这一过程的应用程序开发者将仅需在一处修改这些步骤-工作流本身-而不必担心这样会改变应用程序逻辑。代码复制和在哪里实现该过程可以通过windows wf的使用来加以缓和。
当使用windows wf在asp.net中实现mvc架构时,开发者应该尝试构建独立于应用程序的工作流-而该工作流仍然宿主于该应用程序中。这将有助于保持逻辑独立于描述并且保持在该web应用程序中的工作步骤顺序和页面流之间的高度独立性。
一个wwf开发新手可能试图用一固定数目的活动以某种顺序去开发一个工作流,然后开发一组asp.net web表单–这些表单以与之相同的顺序从一个表单流向另一个表单。很遗憾,尽管这看上去挺符合逻辑,但是实际上这是非常不具有生产效率的,因为你将会再次实现这个工作流逻辑。web页面x不需要知道是否它需要转到页面y或页面z来正确地实现该工作流步骤。代之的是,该工作流(模型)应该告诉asp.net(控制器)下一步该干什么;然后asp.net应该决定要显示哪个页面。这样,每个页面几乎不需要了解整个过程;它仅需要知道怎样完成一个不同的活动并且让该工作流来关心页面是如何从一处流向另一处的。这种分离在开发者处理页面流时带来了一种极大的灵活性。例如,如果你决定改变该页面显示顺序,那么你可以从工作流中容易地实现这一点,而不需要改变该asp.net应用程序中的一行代码。
二、 一个简单的工作流mvc实例
为了说明这一思想,我将向你展示一个简单asp.net应用程序和工作流。这个过度简化的工作流描述了一个进度-收集一些来自于一外部应用程序的私人信息,然后显示它。步骤如下:
1. 调用一个方法–这意味着请求一个人的名字;该工作流使用了invokemethod活动(见图1)。
2. 等待直到一个事件被激发–这意味着收到一个名字;在这一步中,该工作流使用了eventsink活动。
3. 使用一类似调用,从宿主获得一个电子邮件地址。
4. 等待一个事件意味着收到一个地址。
5. 在收到名字和电子邮件以后,该工作流启动一个invokemethod活动来发送个人资料到调用者应用程序。在一种真实世界情形,这最后一步并不很重要。更可能的是,你将调用一个web服务来发送数据到另外的系统,或把它放进一数据库。
“system.workflow.runtime.hosting.aspnetthreadingservice,
system.workflow.runtime, version=3.0.00000.0,
culture=neutral, publickeytoken=31bf3856ad364e35″/>
workflow.library, version=1.0.0.0, culture=neutral,
publickeytoken=c4620ae819b5257e”/>
<add type=”workflow.runtimeservices.getemailservice,
workflow.library, version=1.0.0.0, culture=neutral,
publickeytoken=c4620ae819b5257e”/>
<add type=”workflow.runtimeservices.senddataservice,
workflow.library, version=1.0.0.0, culture=neutral,
publickeytoken=c4620ae819b5257e”/>