可扩展工作流模型的声明性表示的制作方法

文档序号:6647143阅读:283来源:国知局

专利名称::可扩展工作流模型的声明性表示的制作方法
技术领域
:本申请的实施例涉及工作流建模领域。更为具体地,本发明的实施例涉及组件化和可扩展工作流模型。
背景技术
:现有系统试图通过对商业问题建模而将商业问题映射到高级工作流。然而,真实世界的工作流在各方面都有所不同,这些方面诸如(a)执行和建模的复杂性、(b)设计时对工作流的结构的知识、(c)静态定义或特别/动态、(d)在其生命周期中各点创作和编辑该工作流的简易性、以及(e)与核心工作流过程的弱或强商业逻辑关联。现有模型无法容纳所有这些因素。此外,大多数现有工作流模型是以基于语言的方法(例如,BPEL4WS、XLANG/S和WSFL)或基于应用程序的方法为基础的。基于语言的方法是具有一闭合的预定义构造集的高级工作流语言,它帮助向用户/程序员建模该工作流过程。工作流语言载有供该闭合构造集使用的所有语义信息,以使用户能够构建工作流模型。然而,语言无法由开发者来扩展,且表示构成该工作流模型的闭合的原语集。语言被绑定到由工作流系统销售商发货的语言编译器。仅该工作流系统产品销售商可通过在该产品的未来版本中用一新的构造集扩展该语言来扩展该模型。这通常要求升级与该语言相关联的编译器。基于应用程序的方法是这样一种应用程序,它在该应用程序内具有工作流能力以解决领域专用问题。这些应用程序不是真正可扩展的,也没有可编程模型。采用现有方法,复杂性、预知、动态工作流、创作简易性以及与商业逻辑和核心工作流的关联强度等问题未被充分地解决。没有可扩展、可定制以及可重新主宿工作流设计器框架可用于构建可视工作流设计器来对不同的工作流类别建模。现有系统缺乏一种快速应用程序开发(RAD)风格工作流设计体验,它允许用户图形地设计工作流过程,并以开发者选择的编程语言来关联商业逻辑。另外,没有启用了墨迹的工作流设计器。另外,现有系统无法提供用于执行工作流的无缝特别或动态编辑。工作流过程在本质上是动态且移动的,且其形式不能在设计时完全预见。该工作流过程以结构化方式起始,并最终在其执行生命周期过程中发展和改变。需要一种允许工作流构建者能够在设计时创作各种类型的工作流模型,以及以无缝的方式对运行的工作流做出特别或动态改变的工作流创作框架。即使在部署了工作流过程之后且该工作流过程正在运行,商业需求的变化通常迫使改变或编辑当前运行的工作流过程。需要一种提供工作流过程的运行时创作的系统。另外,工作流过程处理跨越工作流过程模型的多个步骤的横切的、互不相关且紊乱的问题。例如,尽管工作流过程的各部分被设计成参与长期运行的事务,然而同一过程的其它部分被设计成用于并发执行。同一工作流过程的另外一些部分要求跟踪,而其它部分处理商业或应用程序级例外。需要向工作流过程的一个或多个部分应用特定的行为。某些工作流建模方法是不实用的,因为它们需要整个商业过程的基于流的完整描述,包括所有例外以及人类干预。这些方法中的一些提供了当出现例外时的附加功能,而其它方法独占地采用基于约束的方法而非基于流的方法来对商业过程建模。现有系统实现基于流或基于约束的方法中的任一种。这些系统该不灵活,以致于无法对许多常见商业情况进行建模。因此,需要一种组件化且可扩展的工作流模型来解决这些和其它缺点的一个或多个。
发明内容本发明的实施例提供了一种用于构建组件化工作流模型的可扩展框架。具体地,工作流过程中的每一步骤具有描述工作流步骤的设计时方面、编译时方面以及运行时方面的相关联组件模型。此外,任何开发者可通过创作这些组件来扩展核心工作流模型。本发明包括一工作流引擎,它足够灵活和强大来协调各种工作流的执行,包括高度形式的机器到机器过程、基于约束的特别人类工作流、以及具有基于流和基于约束的方法的混合的工作流。该工作流引擎准许对执行工作流的激活、执行、查询和控制能力。例如,本发明准许对执行工作流的特别和动态改变。该工作流引擎可以在包括服务器和客户机环境两者的各种宿主环境中重新主宿或嵌入。每一特定宿主环境将工作流引擎与一组服务提供者相结合。服务提供者的总能力确定了可在该特定宿主环境中执行的工作流的种类。本发明的其它实施例提供了一种用于序列化工作流模型的声明性格式,诸如可扩展配合(orchestration)标记语言(XOML)。该声明性格式使用户能够通过编写一组组件来扩展工作流模型。对应于工作流过程的各步骤的语义被封装在活动确认器组件中,该组件在编译时确认并实施给定组件的语义。本发明的声明性格式的实施例还能够进行数据声明以及与工作流模型的各元素的数据相关。该声明性格式支持数据通过工作流的变换。例如,该格式声明性地表示外部数据源,如数据库或文件、代码片断以及工作流模型内的商业规则。本发明的一个实施例提供了一种构建图形/可视工作流设计器的可扩展、可定址以及可重新主宿的工作流设计器框架,以对不同类别的工作流建模。本发明的另一实施例支持快速应用程序开发风格的工作流设计体验,以允许用户图形地设计工作流过程,并以任何编程语言来关联商业逻辑。本发明的实施例也使用笔和图形输入板技术提供了墨迹支持。本发明提供了一种自由形式的绘图表面,其中,由用户绘制的工作流被转移到内部表示。本发明支持通过在现有绘图表面上的墨迹编辑(例如,添加/删除活动)以及现有工作流的墨迹注释(例如,书写表面上的注解、建议或提醒等手绘物)对工作流的创建和修改。本发明的其它一些实施例提供了用于以声明性方式捕捉横切行为并将行为应用于工作流模型的选中部分的组件。本发明的其它实施例在与其相关联的行为的上下文中执行工作流模型的选中部分。本发明的实施例提供了处理工作流模型的多个步骤的横切的、互不相关且紊乱的问题的框架、可重新使用组件和语言。依照本发明的一方面,一种计算机化的方法创建和编译声明性文件。该声明性文件在其中具有多个活动。排列该多个活动以创建由用户定义的工作流。该计算机化方法包括接收对应于由用户定义的工作流的多个活动。该方法也包括标识多个序列化器。所标识的多个序列化器的每一个与所接收的多个活动的至少一个相关联。该方法也包括执行所标识的多个序列化器以将多个活动的元数据转移到工作流的声明性表示。元数据定义了与多个活动的每一个相关联的功能。依照本发明的另一方面,一个或多个计算机可读介质具有用于创建和编译声明性文件的计算机可执行组件。该声明性文件在其中具有多个活动。排列多个活动以创建由用户定义的工作流。多个活动的每一个具有与其相关联的序列化器和元数据。该组件包括用于接收对应于由用户定义的工作流的多个活动的接口组件。该组件也包括用于标识多个序列化器的元数据组件。所标识的多个序列化器的每一个与接口组件接收的多个活动的至少一个相关联。该组件也包括用于执行由元数据组件标识的多个序列化器的序列化组件,用于将多个活动的元数据转移到工作流的声明性标识。元数据定义了与多个活动的每一个相关联的功能。依照本发明的又一方面,一种系统创建和编译其中具有多个活动的声明性文件。该系统包括用于储存多个活动的存储器区域。排列多个活动以创建由用户定义的工作流。该存储器区域还储存多个活动的每一个的序列化器和元数据。该元数据定义了与多个活动的每一个相关联的功能。该系统还包括被配置成执行用于从存储器区域检索多个活动的计算机可执行指令的处理器。该多个活动对应于由用户定义的工作流。该处理器还被配置成执行用于从存储器区域中标识多个序列化器的计算机可执行指令。所标识的多个序列化器的每一个与接收到的多个活动的至少一个相关联。该处理器还被配置成执行用于执行所标识的多个序列化器来将多个活动的元数据从存储器区域转移到工作流的声明性标识的计算机可执行指令。可替换地,本发明可包括各种其它方法和装置。其它特征部分是显而易见的,而部分将在后文指出。图1是包含任务和控制流合成活动的示例性工作流。图2示出了一个示例性活动继承树。图3示出了一个示例性组件模型。图4示出了一个示例性组件模型生命周期。图5是用于创作依赖于工作流规范的向导的工作流的高级应用程序用户界面。图6示出了一个示例性工作流设计器。图7示出了包括接收活动及其后的发送活动的配合程序。图8以图表示出了对象的序列化。图9示出了可视工作流、工作流的序列化表示以及工作流的分离代码之间的进度表定义和关系。图10是示出其中可实现本发明的合适的计算系统环境的一个示例的框图。附录A描述了示例性活动。附录B描述了可扩展配合标记语言(XOML)的示例性实现。附录C描述了用于序列化和反序列化工作流和工作流文件的应用程序编程接口。计算机程序清单附录是依照本发明的软件程序的一个实施例的示例性清单。如上所述,它与本申请一起包括在CD-ROM上。贯穿附图,对应的参考符号指示对应的部分。具体实施例方式本发明的实施例对表示诸如商业过程等过程的工作流进行建模。商业过程是导致可预测和可重复结果的依赖性和有序的任务、活动等。包括组织的操作过程、机构的工作知识以及信息资源,商业过程被设计成以有效且及时的方式满足所定义的商业目标。在一个有效的环境中,过程的功能性组件可被容易地标识、适应和部署来解决不断改变的企业需求。工作流是与商业过程中的任务交互的最终用户的体验。任务被建模为活动、组件等,其每一个表示由个人或机器执行的工作单元。在一个实施例中,向用户呈现多个活动。用户选择并组织活动来创建工作流。执行所创建的工作流以对商业过程建模。参考图1,示例性工作流100包含任务和控制流合成活动。在一个示例中,配合引擎工作流模型支持不同类别工作流的建模、创作和执行。示例包括按照出现在有序序列中或作为一组异步事件出现的一组结构化步骤对给定问题建模。该配合引擎协调进度表的执行。进度表是以树形结构分层排列的一组经组织的活动。执行活动的执行上下文以及对其可见的共享数据由一作用域提供。每一活动表示封装工作流过程中步骤元数据的组件。活动是工作流模型中的基本执行单元,且具有相关联的属性、句柄、约束和事件。每一活动可以由任何编程语言中的用户代码来配置。例如,用户代码可表示以公用语言运行时环境(CLR)语言书写的商业或应用程序逻辑或规则。每一活动支持对用户代码中的执行的预截听(pre-interception)挂钩和后截听(post-interception)挂钩。每一活动具有相关联的运行时执行语义和行为(例如,状态管理、事务、事件处理和异常处理)。活动可与其它活动共享状态。活动可以是原语活动或被组合成合成活动。原语或基本活动没有子结构(例如,子活动),并由此是树结构中的叶节点。合成活动包含子结构(例如,它是一个或多个子活动的父节点)。在一个实施例中,活动有三种类型简单活动、容器活动和根活动。在本实施例中,在模型中有一个根活动,且根活动中没有或有任何数量的简单活动或容器活动。容器活动可包括简单或容器活动。整个工作流过程可用作构建更高阶工作流过程的活动。此外,活动可以是可中断或不可中断的。不可中断合成活动不包括可中断活动。不可中断活动缺少可导致活动阻断的服务。配合引擎提供一组示例性的活动。参考图2,一活动继承树示出了若干示例性活动。图2列出的示例性活动在附录A中更详细地描述。另外,任何用户可编写一个或多个活动来扩展工作流模型。例如,用户可为特定的商业问题、领域、工作流标准(例如,商业过程执行语言)或目标平台编写活动。配合引擎可向用户提供一组丰富的服务来编写活动,该组服务包括,例如分析代码、类型分解和类型系统的服务、用于序列化和呈现的服务。在一个实施例中,每一活动具有至少三个部分元数据、实例数据和执行逻辑。活动的元数据定义了可被配置的数据属性。例如,某些活动可共享在活动抽象基类中定义的一组公用元数据。每一活动依照其需求通过扩展该类来声明其自己的附加元数据属性。元数据属性的值由该活动跨配置该活动的进度表的实例的所有实例共享。例如,如果用户创建进度表A,并向其添加一发送活动,则该发送活动被给予标识信息(例如,“001”)作为其元数据的一部分。添加到该进度表的第二发送活动将接收其自己的唯一标识信息(例如,“002”)。一旦创建和执行了进度表A的多个实例,则发送“001”的所有实例将共享元数据值。相反,活动的实例元数据定义了一组对运行进度表实例中的活动实例专用的数据。例如,延迟活动可提供其实例数据上的只读属性,该实例数据是标识延迟活动的超时值的日期和时间值。一旦延迟活动开始执行,该值即可用,且它对延迟活动的每一单个实例很可能是不同的。通常参考进度表的实例,尤其是活动和任务的实例,而不用“实例”来限定参考。合成活动具有其子活动组作为另一元素。子活动在一个实施例中被认为是元数据。配合引擎模型明确地准许在运行时在进度表的实例中操纵该元数据。向作为执行进度表实例的一个部分的合成活动添加新的子活动,使得仅该进度表实例的元数据(活动树)被影响是可能的。接下来参考图3,每一活动具有一组相关联的组件,它们形成了该活动的组件模型。该组相关联的组件包括活动执行器、活动设计器、活动序列化器、活动确认器(例如,语义检查器)、以及活动代码生成器。活动执行器是实现该活动的执行语义的无状态(stateless)组件。活动执行器与活动的元数据一起工作来实现该活动。代码调度器担当活动执行器的服务提供者以向活动执行器提供服务。活动设计器可视地显示活动的设计时可视表示。活动设计器是设计器分层结构中的一个节点,并且可以加主题或加皮肤。活动设计器主宿在设计环境中(例如,应用程序),并通过服务与宿主设计环境交互。活动确认器在编译时以及运行时实施活动语义。活动确认器在工作流模型的上下文中操作,并使用由该环境提供的服务(例如,编译器、设计器或运行时环境)。确认在工作流生命周期中的各个点发生。结构依从性检查在创建工作流的序列化表示时、编译时或响应于用户请求而做出。语义检查可以在运行时比在编译时执行的检查更强大,以确保诸如运行实例的活动树中活动的添加和替换等运行时操作的安全性。本发明评估与每一活动相关联的语义,以找出例如与预定接口要求的一致性和依从性。活动序列化器是序列化活动元数据的组件。活动序列化器从各种模型/格式序列化器中调用。整个工作流模型是基于一可扩展模式被序列化成声明性标记语言的,它可以按需进一步被转换成其它工作流语言。在一个实施例中,活动的组件模型作为数据结构储存在计算机可读介质上。在该数据结构中,活动设计器由储存用于可视地表示该活动的数据的图像字段(例如,图标)表示。另外,一个或多个创作时字段储存定义与活动相关联的属性、方法和事件的元数据。活动序列化器由储存用于将储存在创作时字段中的元数据传送到活动的声明性表示的数据的序列化器字段表示。活动生成器由储存与储存在创作时字段中的元数据相关联的软件代码的商业逻辑字段来表示。活动执行器由储存用于执行储存在商业逻辑字段中的软件代码的数据的执行器字段表示。作用域和进度表执行活动的执行上下文以及对其可见的共享数据由作用域来提供。作用域是核心活动之一。作用域是用于将变量和长期运行服务与事务语义、出错处理语义、补偿、事件处理程序和数据状态管理集合在一起的统一构造。作用域可具有相关联的异常和事件处理程序。在一个实施例中,作用域可以是事务的、原子的、长期运行的或同步的。在对用户变量的冲突读-写或写-写访问的情况下,向用户提供并发控制。作用域也是事务边界、异常处理边界以及补偿边界。由于作用域可以在进度表内嵌套,因此用不同作用域内相同的名字(即使作用域是嵌套的)来声明变量、消息、通道和相关集而没有名字冲突也是可能的。在进度表内嵌套的作用域只能在该进度表的上下文内执行。进度表可以被编译为应用程序(例如,独立的可执行实体)或库(例如,用于从其它进度表调用)。被编译为库的每一进度表有效地构成了可从其它进度表内调用的新活动类型。进度表的元数据包括参数的声明。一旦开发了进度表,可执行所开发的进度表的实例。激活和控制进度表实例的过程是由其中嵌入了配合引擎的宿主环境所决定的。配合引擎提供了可用于测试进度表的不提供必要服务的“简单宿主”。另外,配合引擎提供了一激活服务来促进同样由引擎和外部应用程序用于与服务环境(即,宿主)交互的“服务提供者”模型(例如,应用程序编程接口)的标准化。激活服务创建了特定进度表类型的进度表实例,并可任选地传递参数。进度表实例本质上是运行进度表实例的代理,并包括唯一地标识该实例的标识符、对进度表的元数据(活动树)的引用、以及挂起、恢复和终止实例的方法。激活服务也支持基于给定的进度表实例标识符找出进度表实例。代码分离(code-beside)作用域活动可具有包括用于该作用域活动的商业逻辑的相关联的代码分离类。由于进度表本身是作用域,因此进度表也可具有代码分离的类。在进度表内嵌套的作用域也可具有其自己的代码分离类。在作用域内嵌套的活动共享该作用域的代码分离类,它担当其共享数据的状态和商业逻辑的容器。例如,代码活动的元数据包括对具有代码分离中的特定签名的方法的引用。在另一实例中,发送活动的元数据包括对特定签名的代码分离方法的可任选引用加上对消息声明和通道声明的强制引用。代码分离的示例性使用包括变量、消息、通道和相关集的声明;出/入/引用参数的声明;附加自定义属性的声明;要发送的消息的准备;已接收消息的处理;以返回布尔值的代码表达的规则的实现;本地定义的变量的操纵;读活动元数据和实例数据;写活动实例数据(例如,设置将要执行的活动的属性);引发事件;抛出异常;枚举和导航运行进度表实例的活动树中的活动的分层结构,包括跨嵌套的作用域和进度表调用边界;向运行进度表实例内的合成活动添加新活动;改变与运行进度表实例内的活动相关联的声明性规则;以及获取对其它运行进度表实例的引用和对其的操纵。参考图4,一框图示出了示例性组件模型生命周期。用户与储存在一个或多个计算机可读介质上的计算机可执行组件交互。计算机可执行组件包括接口组件402、元数据组件404、序列化组件406以及确认组件408。接口组件402接收对应于由用户定义的工作流的多个活动。元数据组件404标识多个序列化器,其每一个与由接口组件402接收的多个活动中的至少一个相关联。序列化组件406执行由元数据组件404标识的多个序列化器,以将该多个活动的元数据传输到工作流的声明性标识。确认组件408将传输的元数据映射到可扩展模式定义名字空间以供确认。在一个实例中,工作流的声明性表示(例如,文件)包括储存具有该工作流的标识信息的清单的数据结构。示例性标识信息包括与该文件相关联的名字、版本、描述以及身份中的一个或多个。该文件也包括与工作流相关联的多个活动的列表,以及与每一活动相关联的属性(例如,CLR类型)、方法和事件的列表。工作流模板(stencil)工作流模板(例如,工作流样板或活动包)包括根活动和一组活动。模板可以是域或宿主专用的。模型的示例包括结构化的工作流模板、人类工作流模板以及非结构化的工作流模板。某些模板可以作为一组活动是“闭合的”,包括被设计成可能在特定的宿主环境中共同工作的一个或多个根。其它模板可能是“开放”到各种程度的。模板定义了其可扩展性点。例如,开发者编写CustomRoot(自定义根)和新的抽象CustomActivity(自定义活动),并声明包是CustomRoot加上从CustomActivity导出的任何活动。示例性BPEL或XLANG/S模板包括具有以下特征的根活动状态管理和事务中的参与具有相关联的事件和异常处理程序、支持合约第一模型、可被分析、并具有定义良好的激活和终止行为。示例性模板还包括一组消息通信专用活动(例如,Send(发送)和Receive(接收)及其变体),以及诸如Scope(作用域)、Loop(循环)、Condition(条件)、Listen(监听)和Throw(抛出)等其它结构化活动。一个示例性Halifax模板包括具有以下特征的根活动隐含状态管理、相关联的异常处理程序(0-n)、支持基于事件的模型、具有良好定义的激活行为、以及具有未定义的终止。根活动包含0-n个EventDriven(事件驱动)活动。每一EventDriven活动表示一个Halifax活动。每一EventDriven活动具有相关联的状态管理协议并在原子作用域内执行。设计器框架(用户界面)配合引擎提供了用于以WYSWYG方式设计各种类别的工作流模型的框架。例如,参考图5,一种用于创作工作流的高级应用程序用户界面依赖于工作流规范的向导。该框架包括使开发者能够编写可视工作流设计器的一组服务和行为。这些服务提供了呈现工作流过程的有效方式、支持用于绘制工作流的墨迹/图形输入板、以及支持诸如撤消/回复、拖/放、剪切/复制/粘贴、缩放、扫视、搜索/替换等设计器操作、书签、装饰、用于确认错误的智能标签、用于活动的有效拖动目标指示符、自动布局、视图分页、导航标记器、拖动指示符、具有页眉/页脚的打印和预览等等。通过这一用户界面,可构造包含任务和控制流合成活动(例如,顺序、并行和条件)的简单工作流。对规则规范(例如,条件分支逻辑、while循环逻辑)或数据流规范(例如,任务A的输出是任务B的输入)不要求代码输入(或依赖于现有的已编译代码)。进度表的序列化表示(包括规则和数据流)是自包含的,且在不需要代码分离的某些情形中完成。使用本发明的设计器框架,本发明的配合引擎包括一种快速应用程序开发(RAD)风格的可视工作流设计器,它支持以可视方式将软件代码与工作流模型相关联。工作流中的每一活动具有相关联的活动设计器。每一活动设计器是按照框架服务来编写的。本发明的框架也包含一可视设计器模型。该可视设计器模型包括通过该工作流模型中的关系彼此链接的一组活动设计器。图6示出了一个示例性工作流设计器。本发明包括将代码与工作流模型相关联的各种模式,包括“代码分离”、“代码嵌入”和允许用户代码实时在工作流模型中往返的“仅代码”。本发明也提供了当用户在构建工作流时的实时语义错误。在一个实施例中,本发明向用户呈现了标识设计器框架用户界面中的多个活动的包。本发明还从用户接收对所呈现的活动的选择和分层组织。本发明序列化所接收的活动来创建工作流的持久表示。本发明还从用户接收表示用于与工作流中的多个活动之一相关联的商业逻辑的软件代码。本发明也可接收具有与其相关联的一个或语义的用户定义活动。本发明包括用于评估语义以找出其对预定义接口要求的一致性的语义检查器或确认器。如果语义与预定义的接口要求相一致,则本发明呈现该用户定义的活动作为多个活动之一。本发明还编译软件代码来创建一个或多个二进制文件。例如,本发明将序列化的工作流表示和软件代码编译成包含工作流的可执行表示的单个程序集(assembly)。本发明执行所创建的工作流。在一个实施例中,一个或多个计算机可读介质具有用于执行该方法的计算机可执行指令。配合引擎设计器允许用户通过使用其它所创建的进度表来递归地组成更高阶进度表并使用它们。进度表的内联扩充允许用户内联地查看进度表内容并剪切或复制内容。为允许进度表的内联扩充以及使进度表只读,创建用于内联进度表的单独设计表面和设计器宿主。此外,合成进度表设计器具有其自己的分层结构。所调用的进度表在设计器由用户扩充时被加载和显示。在一个实施例中,当活动被放到或复制到设计器表面上时,层叠设计器。一属性将调用活动设计器与主宿的进度表的根设计器链接。以下函数防止向设计器添加或移除活动。internalstaticboolAreAllComponentsInWritableContext(ICollectioncomponents)internalstaticboolIsContextReadOnly(IServiceProviderserviceProvider)这些函数由基础结构调用以检查其中插入活动的上下文是否为可写的。对于主宿的设计器,这些函数返回假。另外,防止属性被修改。其它函数从适当的组件中取出活动设计器internalstaticServiceDesignerGetSafeRootDesigner(IServiceProviderserviceProvider)internalstaticICompositeActivityDesignerGetSafeParentDesigner(objectobj)internalstaticIActivityDesignerGetSafeDesigner(objectobj)在一个示例中,用户创建进度表并将其编译为活动。在成功地编译之后,该进度表出现在工具箱中。用户打开或创建其中需要所编译的进度表的进度表。用户从工具箱中拖放所编译的进度表。在设计表面上示出层叠的进度表设计器。当用户希望查看放下的所编译的进度表的内容时,用户扩充进度表设计器以用只读的状态示出内联的所调用的进度表的内容。所调用的进度表的内联使用户能够查看所调用的进度表,而无需在不同的进度表设计器之间切换。该特征对于通过重复使用现有进度表来组成更高阶进度表的开发者而言是有用的。对使用主题/皮肤的设计器框架的定制的支持使用设计器框架编写的工作流设计器可使用工作流主题来定制。这些可以是声明性地描述设计器的各方面的可扩展标记语言(XML)文件。工作流设计器提供伙伴扩展活动的向导支持。工作流设计器支持的示例性用户界面特征包括,但不限于,撤消/恢复、拖/放、剪切/复制/粘贴、缩放、扫视、搜索/替换、书签、装饰、用于确认错误的智能标签、用于活动的有效拖动目标指示符、自动布局、视图分页、导航标记器、拖动指示符、具有页眉/页脚的打印和预览、以及文档大纲综合。工作流设计器支持自定义的设计器主题/皮肤来允许使用XML元数据定制设计器的外观和感觉。工作流设计器支持后台编译。在一个实施例中,提供了在设计进度表时用于确认错误的智能标签和智能动作。工作流设计器可主宿在任何容器中(例如,应用程序、外壳等)。一个示例性配合引擎程序包括接收活动以及其后跟随的发送活动。基本上,该过程接收消息并将其发送出去。用户创建名为“HelloWorld”的项目,并向该项目添加配合项。用户然后将作用域活动拖放至设计表面。下一步,用户将接收活动以及其后的发送活动放到该作用域上。图7示出了设计器中的所得工作流700。每一活动设计器提供了对象模型上的用户界面表示。开发者能够直接对对象模型编程,并设置活动上的属性或使用该设计器。配合引擎设计器允许开发者从工具箱中选择活动并将其拖到设计器表面上。如果活动已被放置到进度表中并需要移动,则开发者能够选择它(通过点击它)并将其拖至它需要去往的进度表区域。如果开发者按住ctrl键并同时进行拖放,则做出所选中活动的副本。积极放置提供了可能的拖动点(目标)作为设计表面上的可视指示器。自动滚动也参与在拖放的上下文中。当处理大型进度表时,到当前不在视见区中的设计器区域的导航可通过将该活动拖向要放置的进度表区域来访问。拖放可跨统一项目中的进度表以及跨统一解决方案中的其它项目中的进度表得到支持。在活动被放置到设计表面上之后,开发者配置该活动。每一活动具有一组属性,开发者配置该属性以使进度表有效。这些属性可在属性浏览器中编辑。每一活动控制什么属性在属性浏览器中是可查看的。为帮助开发者配置各活动,设计器提供了各种对话框或“子设计器”。对活动的各属性调用每一对话框。配合引擎能够定制工具箱中呈现的活动。当开发者创建自定义活动或进度表时,最终的结果是程序集。使用对话框,开发者能够浏览程序集位置并选择该程序集以使其作为配合引擎活动出现。或者,开发者可将程序集放置在配合引擎安装路径中,且它也作为配合引擎活动呈现。应用程序编程接口(API)在另一实施例中,本发明提供了用于执行各种工作流操作的应用程序编程接口(API)。本发明包括用于创作工作流的设计应用程序编程接口。设计应用程序编程接口包括用于创作工作流的装置以及用于选择一个或多个活动来创建该工具流的装置。本发明也包括用于编辑经由设计应用程序编程接口创作的工作流的编译应用程序编程接口。编译应用程序编程接口包括用于序列化工作流的装置、用于定制工作流的可视外观的装置、用于编译经由设计应用程序编程接口创作的工作流的装置、用于确认工作流的装置。本发明也包括用于将类型与工作流中的每一活动相关联的类型提供者应用程序编程接口。类型提供者应用程序编程接口包括用于将该类型与工作流中的每一活动相关联的装置,以及用于将一类型与工作流中的每一活动相关联的装置。硬件、软件以及一个或多个应用程序编程接口(API)构成了用于创作工作流的示例性装置、用于选择一个或多个活动来创建工作流的示例性装置、用于序列化工作流的示例性装置、用于定制工作流的可视外观的示例性装置、用于确认工作流的示例性装置、用于编译工作流的示例性装置、以及用于将类型与工作流中的每一活动相关联的示例性装置。活动执行框架由于有进度表和作用域的例外,因此引擎将活动视为抽象的实体,并仅协调活动的执行而不知道任何特定活动的具体数据或语义。在一个实施例中,四个实体在活动的执行期间交互活动本身、正在执行的活动的父活动、包含正在执行的活动的作用域、以及配合引擎。每一实体具有不同的功能。如果活动的执行方法返回而没有向其活动协调器发信号通知完成,则该活动被认为是在逻辑等待状态中。这一活动可由配合引擎取消,或继续(例如,一旦它所等待的项或事件变得可用或发生,且由引擎向该活动通知这一情况)。某些从未进入逻辑等待状态的活动可能从不被取消。示例包括发送活动和代码活动,因为它们不需要对外部事件或预定的需求就可执行。一旦交出了线程(即,一旦其执行方法由配合引擎调用),则这些活动将做工作直到完成。从不给配合引擎取消它们的机会,因为它们不返回线程直到它们发信号通知完成。配合引擎运行时环境使用规则来触发在其上执行配合引擎活动的事件。配合引擎设计器向用户提供了在运行时关联要评估的规则来触发事件的能力。配合引擎设计器通过提供可扩展性体系结构使用户能够使用不同类型的规则技术。该设计器对于所使用的规则技术的类型是不可知的。在一个实施例中,设计器支持布尔表达式处理程序,作为将规则与活动相关联的一种方式。这意味着在用户代码文件中,用户编写返回真或假值的方法,基于该方法触发规则。当前有多种可用于评估规则的技术,包括信息代理(InfoAgent)和商业规则引擎(BRE)。为实现这一目标,设计器包括使规则技术开发者能够在设计器中主宿自定义用户界面的可扩展性体系结构。该设计器提供了一种自定义用户界面编写者以代码语句集合的形式序列化规则的方法。该设计器在用户代码文件中发放布尔处理程序,并向其插入代码语句集合。配合引擎包括可由规则编写者使用的默认用户界面。规则技术提供者通过创建自定义规则声明、编写与自定义规则声明相关联的用户界面类型编辑器、创建自定义用户界面来主宿规则用户界面、以及在保存时生成代码语句来向配合引擎设计器添加规则。在一个示例中,用户选择要向其附加规则的活动设计器、在属性浏览器中定位规则属性并在下拉框中选择“RuleExpressionHandler(规则表达式处理程序)”(它使得“Statements(语句)”属性出现在用户界面的Rule(规则)属性下方)、在“Statements”属性中指定用户代码方法名、调用用户界面类型编辑器来调用主宿规则专用用户界面的对话框、以及在对话框中通过创建新的谓词行并将它们组合在一起来定义规则。用户界面在用户代码文件中发放方法。方法名将与由用户在属性浏览器中指定的名称相同。等效于创建规则的代码语句将被插入到该规则的用户代码方法中。执行期间的消息通信在运行工作流中,发送到进度表的消息是预期供特定进度表实例使用的。例如,购买定单#123的发票必须被发送回发起(例如,发送出)该购买定单的同一进度表实例。为将入站消息与适当的进度表实例相匹配,消息和进度表实例共享一相关集。该相关集可以是单值相关集,这意味着消息中的标识符字段与由进度表实例持有的相同类型的标识符进行匹配。多属性相关集也是可能的,且类似于数据库表中的多列主要关键字。进度表实例持有的相关集的值是在进度表实例发送出消息时初始化的(例如,可从出栈定单的标识符字段中取该值),或当进度表实例接收消息时初始化的。该相关集值然后是该进度表实例状态的一部分。当随后的入站消息到达时,进度表实例状态中保持的相关集值与由预期类型的入站消息所持有的标识符字段进行匹配。当找到匹配,则满足该相关集,且该消息被传递到进度表实例。尽管相关集的实现是由配合引擎和宿主环境所决定的,但是在一个实施例中,用户声明该相关集以使进度表实例能够正确工作。在另一实施例中,某些活动(例如,SendRequest(发送请求)/ReceiveResponse(接收响应)活动以及ReceiveRequest(接收请求)/SendReponse(发送响应)活动)与用户无关地设置相关集。由发送和接收活动执行各种各样的确认检查,以确保相关集是正确初始化和遵循的。执行工作流的动态编辑配合引擎提供了用于创作(以及随后可视化和执行)各种类型的工作流的框架。示例包括事件-条件-动作(ECA)风格的工作流或结构化工作流或规则驱动工作流。此外,不论是如何对工作流建模的,工作流都允许用户在设计时或甚至在工作流过程正在运行时以同一方式创作或编辑工作流,而无需重新编译该工作流过程。该框架允许用户以高保真度在运行时和设计时表示之间进行往返。特别(adhoc)改变是在运行时对过程模型做出的改变。用户可向运行的实例要求其进度表模型,并向该模型做出改变。例如,用户可按批添加、移除或替换活动,然后提交或回退批处理的改变。在一个实施例中,模型是在更新之后确认的。在本发明的许多工作流情形中,“设计时创作”和“运行时执行”之间的分隔存在模糊或甚至是消除。进度表实例有效地与其它实例共享为那些实例的进度表类型所定义的活动类型(元数据)树。但是一旦开始执行,任何进度表实例可通过添加新活动或操纵声明性规则在进行中改变。采取这一修改的进度表实例并“保存为”新进度表类型,或更一般地,仅从实例中恢复序列化的表示是可能的。即,运行的进度表实例可被序列化,然后将其带入任何设计器(例如,创作环境)或运行时可视化工具。此外,对于高级开发者而言,将进度表完全作为软件代码来创作是可能的。为直接创作进度表类型,开发者只需在该进度表的代码分离类的软件代码中包括称为InitializeScheduleModel(初始化进度表模型)的方法,然后用[ScheduleCreator](进度表创建器)元属性来标记该方法。在一个实施例中,该静态方法不采用任何参数,并返回一Schedule(进度表)对象。没有伴随的序列化文件,尽管可从所创建的Schedule对象中恢复该进度表的序列化表示。尽管这意味着可使用单个软件代码文件来开发进度表,然而可能不在该文件上执行确认检查。配合引擎编译确保作为进度表类型的基础的活动树的结构和语义有效性。在另一实施例中,编译和确认内部地运行,以产生所执行的实际类型,而不要求任何代码输入。进度表类型编译变为一种非常容易的过程,因为没有从编译时对象模型到运行时对象模型的转换。本质上,编译只需将进度表的对象模型表示与代码分离相组合以产生新类型。在一个实施例中,如果所编译的代码分离与对象模型中的活动所需求的相匹配,对特定的进度表可能完全没有任何基本需求来提供任何代码分离,或者代码分离可能已经以编译的形式(程序集)存在。当编译序列化进度表时,指向有效地担当该进度表的代码分离的现有已编译类型是可能的。创建该已编译类型的派生类型,且该新类型担当代码分离以确保创建了唯一的类型来表示该新进度表。序列化体系结构序列化基础结构提供了一种模块化的、格式中立且容易扩展的机制来序列化配合引擎活动树。图8以图表示出了对象的序列化。一般而言,本发明包括用于创建和编译声明性文件的计算机化的方法。该计算机化的方法包括接收对应于由用户定义的工作流的多个活动。在一个实施例中,本发明通过访问储存在存储器中的工作流来接收该多个活动。本发明标识了多个序列化器,其每一个与所接收的多个活动的至少一个相关联。本发明执行所标识的多个序列化器以将与多个活动的每一个相关联的元数据传输到工作流的声明性标识。元数据定义了与多个活动的每一个相关联的功能。例如,与活动之一相关联的元数据定义了与该活动相关联的属性、方法和/或事件。本发明也编译工作流的声明性标识来创建可执行文件。本发明还可将所传输的元数据映射到可扩展模式定义名字空间以供确认。在一个实施例中,一个或多个计算机可读介质具有用于执行该计算机化方法的计算机可执行指令。在一个实施例中,该计算机化方法和应用程序编程接口构成了用于从存储器区域中检索多个活动的示例性装置,所述多个活动对应于由用户定义的工作流;用于从存储器区域中标识多个序列化器的装置,所标识的多个序列化器的每一个与所接收的多个活动的至少一个相关联;以及用于执行所标识的多个序列化器来将多个活动的元数据从存储器区域传输到工作流的声明性表示的装置。具体地,调用者(例如,应用程序或用户)向序列化管理器请求对象(或活动)A的序列化器。对象A的类型的元数据元属性将对象A绑定到所请求类型的序列化器。调用者然后要求序列化器序列化对象A。对象A的序列化器然后序列化对象A。对于在序列化时遇到的每一对象,序列化器向序列化管理器请求另外的序列化器。序列化的结果被返回給调用者。配合引擎组件模型中的每一活动可参与序列化。在一个实施例中,序列化器组件不是活动类本身的一部分。相反,该组件通过在与该活动相关联的类中注释序列化器元属性来指定。序列化器元属性指向用于序列化该活动类型的对象的类。在另一实施例中,活动类型的提供者组件覆盖了由该活动提供的默认序列化器。设计器序列化基于元数据、序列化器和序列化管理器。元数据元属性用于将类型与序列化器相关。“程序引导”元属性可用于安装为没有序列化器的类型提供序列化器的对象。序列化器是知道如何序列化特定类型或类型作用域的对象。对每一数据格式存在一基类。例如,可以有知道如何将对象转换成XML的XmlSerializer(XML序列化器)基类。本发明是独立于任何特定序列化格式的通用体系结构。序列化管理器是对用于序列化对象图的所有各种序列化器提供信息存储的对象。例如,五十个推想的图可具有五十个不同的序列化器,它们都生成其自己的输出。序列化管理器可由这些序列化器使用以在必要时彼此通信。在一个实施例中,与使用类属对象元数据的序列化器耦合的序列化提供者的使用提供了一种回叫机制,其中,给予对象向给定类型提供序列化器的机会。可通过诸如AddSerializationProvider(添加序列化提供者)等方法来向序列化管理器给予序列化提供者。序列化提供者可通过向序列化器添加诸如DefauRSerializationProviderAttribute(默认序列化提供者属性)等元属性而被自动添加到序列化管理器。在一个实施例中,格式由以下规则来规定对象被序列化为xml元素、对象的属性被归类为简单属性(例如,序列化为xml元属性)或复杂属性(序列化为子元素)、以及对象的子对象被序列化为子元素。子对象的定义可在各个对象之间不同。以下示例是while活动的序列化,它具有Send活动作为其子对象之一。<WhileID=″whilel″><ConditionRule><CodeExpressionRuleDeclaration><ExpressionName=″whileCondition″/></CodeExpressionRuleDeclaration></ConditionRule><SendHasTypedChannel=″True″ID=″send1″><MessageName=″msg1″Type=″System.UInt32″/><OnBeforeSendName=″onBeforeSend1″/><TypedChannelType=″System.Collections.IList″Operation=″Addlndex″Name=″Foo″/></Send></While>在其中用于序列化的语言是可扩展配合标记语言(XOML)的实施例中,当编译进度表时,每一XOML元素被序列化成其各自的对象。XOML的一个示例性实现在附录B中描述。XOML对象包括简单和复杂类型两者。接下来描述每一活动的XOML表示之间的映射及其到创作对象模型的映射。XOML的序列化在原语(Primitive)和合成(Composite)活动之间有所不同。原语活动的简单类型被序列化为该活动类型上的元属性。原语活动的复杂类型被序列化为子元素。作为一个示例,以下是Send活动的XOML表示。<SendID=″send1″HasTypedChannel=″False″><MessageName=″message1″Type=″System.String″/><UntypedChannelName=″c1″/></Send>以与原语类型序列化类似的方式,合成活动的简单类型被序列化为该活动类型上的元属性。然而,按照定义,合成活动封装了嵌套的活动。每一嵌套的活动被序列化为另一子元素。作为一个示例,以下是While活动的XOML表示。<WhileID=″while1″><ConditionRule><CodeExpressionRule><ExpressionName=″test″/></CodeExpressionRule></ConditionRule></While>过程/工作流视图和序列化的表示之间存在强关系。图9示出了可视工作流、该工作流的序列化(例如,XOML)表示以及该工作流的分离代码之间的进度表定义和关系。当以任一表示创作时,其它表示将招致改变。由此,当开发者在XOML和过程/工作流视图之间切换时,修改活动的XOML(或在合成活动的情况下修改其构成部分)直接在过程/工作流视图中得到反映。反过来也是适用的。修改过程/工作流视图中的活动导致XOML内的适当修改。作为一个示例,过程/工作流中的活动的删除导致同一活动的XOML中XML元素的移除。在过程/工作流视图和分离的代码之间也发生往返。在创建XOML代码的过程中,如果XOML定义不符合预定义的接口要求,则在违反的XML元素下加下划线,或用其它方式可视地向开发者标识。如果开发者切换到过程视图,则将向他们警告在XOML内存在错误,且设计器提供一链接,开发者可点击该链接并且会被导航到违反的元素。该同一错误出现在任务面板中,并且在双击该错误之后,开发者将会被导航到XOML中违反的元素。CD-ROM上计算机程序清单附录的注释描述CD-ROM上的计算机程序清单附录是依照本发明的XOML模式的一个实施例的示例性清单。XOML模式(见CD-ROM上的计算机程序清单附录,第1-737行)定义了一组示例性活动。CD-ROM上的计算机程序清单附录中的该示例性计算机代码仅是用于本发明的声明性标记语言的一个实施例。在本发明的其它实施例中,CD-ROM上的计算机程序清单附录的计算机程序事件可以用不同的代码、不同的软件模块或在完全综合的基础上书写。从XOML文件创建活动树(反序列化)本发明包括从工作流的声明性表示(例如,XOML)文件反序列化工作流的方法。本发明包括用于为工作流中的每一活动检索储存在工作流的声明性表示中的元数据、编译与工作流中的每一活动相关联的软件代码、以及根据所检索的元数据和所编译的软件代码重新创建工作流。在一个实施例中,CreateEditorInstance()函数(创建编辑器实例)创建DesignSurface(设计表面)对象,然后对DesignSurface对象调用BeginLoad()函数(开始加载),向其传递实际的加载器对象,最终以对DesignerLoader()函数(设计器加载器)的BeginLoad()调用而结束。PerformLoad()函数(执行加载)读取文本缓冲区对象,并将其反序列化到配合引擎组件模型分层结构。本发明走查该分层结构,并将活动插入到设计表面以加载视件工作室(visualsutdio)中的组件。本发明也监听对XOML文件的改变以跟踪分层结构和项标识改变,来更新视件工作室高速缓存中的值。次要文档数据列表包括对用户不可见的次要文档的列表,配合引擎设计器在这些次要文档上工作。例如,用户尚未打开分离代码文件,但当用户在配合引擎设计器中做出改变时,对该分离代码文件做出改变是可能的。由于该文件对用户是不可见的,因此该文件作为次要文档来维护。只要保存XOML文件,就自动保存次要文档。如果这些文件之一的名字改变,或者文件被删除,则本发明相应地更新对应的次要文档对象。对象树的示例性反序列化准则如下。xml元素首先作为父对象的属性来处理。如果父对象没有具有该元素标签名的属性,则该元素作为父对象的子对象来处理。xml元属性作为父对象上的简单属性来处理。在适用上述序列化代码的一个示例性反序列化中,<While>元素作为适用xml名字空间信息创建的对象来处理。<ConditionRule>元素作为While活动的属性来处理。<CodeExpressionRuleDeclaration>元素作为其值将被应用于ConditionRule属性的对象来处理。<Send>元素首先作为While活动的属性来尝试,但“While”活动没有具有名字为“Send”的属性,因此<Send>元素作为对象来处理,并作为子活动添加到while活动。<Message>元素作为Send活动的属性来处理。由于Send上的Message属性是只读的,因此Message元素的内容被认为是Message对象的内容。类似的规则也适用于<OnBeforeSend>和<TypedChannel>元素的反序列化。在以下条件下,XOML反序列化将会严重失败XOML代码不是良好形成的、XomlDocument不是XOML代码中的第一个元素、以及XOML代码中的第一个活动不能被反序列化。将向开发者呈现出错消息,当从XOML视图切换到过程/工作流视图时,通过该消息他们可被导航到违反的XML元素。用于序列化和反序列化的应用程序编程接口在附录C中更详细描述。主宿配合引擎设计器设计器框架可被主宿在任何应用程序中。这对于第三方应用程序要在其各自的环境中呈现工作流而言是非常有用的特征。它也允许第三方通过重新主宿和定址设计器表面来开发关于配合引擎设计器的工具。本发明的框架期望主宿容器应用程序能够提供诸如编辑器和/或文本缓冲区等一组服务。重新主宿设计器的一个步骤是创建加载器和设计表面。加载器负责加载XOML文件,并构造维护活动的设计器宿主基础结构。设计表面维护其中的设计器宿主基础结构,并向宿主提供服务且与设计表面交互。设计表面担当服务容器以及服务提供者。在一个示例中,执行以下代码来加载XOML文档并构造维护其中的活动的设计器宿主。this.loader.XomlFile=filePath;if(this.surface.IsLoaded==false)this.surface.BeginLoad(this.loader);以下服务启用了设计器中的不同函数。ISelectionService函数(选择服务)维护所选中的对象。IToolboxService函数(工具箱服务)管理与工具箱的交互。IMenuCommandService函数(菜单命令服务)管理与菜单的交互。ITypeProvider函数(类型提供者)启用类型系统。另外,可以有由设计器主宿环境提供的其它服务,以启用高级的设计器特征。类型流是本发明的组件模型框架中的一个组件。当设计器主宿在项目系统内部时,在每一项目的基础上创建TypeProvider(类型提供者)对象。项目中的程序集引用被压入类型提供者。此外,对项目中的用户代码文件进行语法分析,并创建单个代码编译且将其压入类型提供者。同样,本发明监听项目系统中将导致类型系统中的类型改变的事件,并响应于改变对类型提供者做出适当的调用来重新加载类型。撤消/恢复在创建且正确地构造了进度表之后,开发者可能希望回退一系列已执行的操作。本发明的撤消和恢复功能提供了可视的反馈,它示出了哪一活动被直接影响。例如,当撤消活动上的属性时,被影响的活动变为选中。当撤消多个对象的删除时,当被恢复到进度表时,所涉及的所有对象变为选中。撤消/恢复是在其它领域的许多应用程序中使用的常见特征,且其意义是被普遍理解的。在配合引擎设计器中,撤消/恢复项在保存时不被清除。此外,撤消/恢复可在过程/工作流视图中、XOML视图中、当开发者在视图之间切换时、以及在分离代码中执行。对过程/工作流视图中的以下动作提供了撤消/恢复活动拖放(例如,将活动从工具箱拖到设计表面、将活动从进度表的一部分移到另一部分、以及将活动从一个设计器移到另一设计器)、活动的配置(例如,指定活动的属性)、以及剪切/复制/粘贴/删除。在一个实施例中,序列化的视图(例如,XOML)视图是提供文本编辑器的标准撤消/恢复操作的XML编辑器。本发明的设计器向开发者提供了反馈,指示过程/工作流视图中做出改变然后在序列化视图中撤消将导致序列化代码的丢失。当开发者在过程/工作流视图中构造进度表的一部分时,切换到序列化视图然后决定执行撤消/恢复操作,将出现警告。示例性操作环境图10以计算机130的形式示出了通用计算设备的一个示例。在本发明的一个实施例中,诸如计算机130等计算机适用于此处所示和所描述的其它附图。计算机130具有一个或多个处理器或处理单元132以及系统存储器134。在所示的实施例中,系统总线136将包括系统存储器134的各种系统组件耦合至处理器132。总线136表示若干类型总线结构的任一种的一个或多个,包括存储器总线或存储器控制器、外围总线、加速图形端口、以及使用各种总线体系结构的任一种的处理器或局部总线。作为示例而非局限,这类体系结构包括工业标准体系结构(ISA)总线、微通道体系结构(MCA)总线、增强ISA(EISA)总线、视频电子技术标准协会(VESA)局部总线以及外围部件互连(PCI)总线,也称为Mezzanine总线。计算机130通常具有至少某种形式的计算机可读介质。计算机可读介质可以是可由计算机130访问的任何可用介质,可包括易失性和非易失性介质、可移动和不可移动介质。作为示例而非局限,计算机可读介质包括计算机存储介质和通信介质。计算机存储介质包括以用于储存诸如计算机可读指令、数据结构、程序模块或其它数据等信息的任一方法或技术实现的易失性和非易失性,可移动和不可移动介质。例如,计算机存储介质包括RAM、ROM、EEPROM、闪存或其它存储器技术、CD-ROM、数字多功能盘(DVD)或其它光盘存储、磁盒、磁带、磁盘存储或其它磁存储设备、或可以用来储存所期望的信息并可由计算机130访问的任一其它介质。通信介质通常具体化为诸如载波或其它传输机制的已调制数据信号中的计算机可读指令、数据结构、程序模块或其它数据,并包括任一信息传送介质。本领域的技术人员熟悉已调制数据信号,它以对信号中的信息进行编码的方式设置或改变其一个或多个特征。有线介质,如有线网络或直接连线连接,以及无线介质,如声学、RF、红外和其它无线介质,都是通信介质的示例。上述任一的组合也应当包括在计算机可读介质的作用域之内。系统存储器134包括易失性和/或非易失性存储器形式的计算机存储介质。在所示的实施例中,系统存储器134包括只读存储器(ROM)138和随机存取存储器(RAM)140。基本输入/输出系统142(BIOS)包括如在启动时帮助在计算机130内的元件之间传输信息的基本例程,通常储存在ROM138中。RAM140通常包含处理单元132立即可访问或者当前正在操作的数据和/或程序模块。作为示例而非局限,图10示出了操作系统144、应用程序146、其它程序模块148和程序数据150。计算机130也可包括其它可移动/不可移动、易失性/非易失性计算机存储介质。例如,图10示出了对不可移动、非易失性磁介质进行读写的硬盘驱动器154。图10也示出了对可移动、非易失性磁盘158进行读写的磁盘驱动器156以及对可移动、非易失性光盘162,如CDROM或其它光介质进行读写的光盘驱动器160。可以在示例性操作环境中使用的其它可移动/不可移动、易失性/非易失性计算机存储介质包括但不限于,磁带盒、闪存卡、数字多功能盘、数字视频带、固态RAM、固态ROM等等。硬盘驱动器154、磁盘驱动器156和光盘驱动器160通常通过非易失性存储器接口,如接口160连接到系统总线136。上文讨论并在图10示出的驱动器及其关联的计算机存储介质为计算机130提供了计算机可读指令、数据结构、程序模块和其它数据的存储。例如,在图10中,示出硬盘驱动器154储存操作系统170、应用程序172、其它程序模块174和程序数据176。注意,这些组件可以与操作系统144、应用程序146、其它程序模块148和程序数据150相同,也可以与它们不同。这里对操作系统170、应用程序172、其它程序模块174和程序数据176给予不同的标号来说明至少它们是不同的副本。用户可以通过输入设备或用户界面选择设备,如键盘180和定位设备182(例如,鼠标、跟踪球或触摸垫)向计算机130输入命令和信息。其它输入设备(未示出)可包括麦克风、操纵杆、游戏垫、圆盘式卫星天线、扫描仪等等。这些和其它输入设备通常通过耦合至系统总线136的用户输入接口184连接至处理单元132,但是也可以通过其它接口和总线结构连接,如并行端口、游戏端口或通用串行总线(USB)。监视器188或其它类型的显示设备也通过接口,如视频接口190连接至系统总线136。除监视器188之外,计算机通常包括其它外围输出设备(未示出),如打印机和扬声器,它们可通过输出外围接口(未示出)连接。计算机130可以使用到一个或多个远程计算机,如远程计算机194的逻辑连接在网络化环境中操作。远程计算机194可以是个人计算机、服务器、路由器、网络PC、对等设备或其它普通网络节点,并通常包括许多或所有相对于计算机130所描述的元件。图10描述的逻辑连接包括局域网(LAN)196和广域网(WAN)198,但也可包括其它网络。LAN136和/或WAN138可以是有线网络、无线网络、其组合等等。这类网络环境常见于办公室、企业作用域计算机网络、内联网以及全球计算机网络(例如,因特网)。当在局域网网络环境中使用时,计算机130通过网络接口或适配器186连接至LAN196。当在广域网网络环境中使用时,计算机130通常包括调制解调器178或用于通过WAN198,如因特网建立通信的其它装置。调制解调器178可以是内置或外置的,它通过用户输入接口184或其它适当的机制连接至系统总线136。在网络化环境中,相对于计算机130所描述的程序模块或其部分可储存在远程存储器存储设备(未示出)中。作为示例而非局限,图10示出远程应用程序192驻留在存储器设备上。示出的网络连接是示例性的,也可以使用在计算机之间建立通信链路的其它装置。一般而言,计算机130的数据处理器通过在不同的时刻储存在计算机的各种计算机可读存储介质中的指令来编程。例如,程序和操作系统通常分布在软盘或CD-ROM上。从那里,它们被安装或加载到计算机的次级存储器中。在执行时,它们被至少部分地加载到计算机的初级电子存储器中。此处描述的本发明包括这些和其它各种类型的计算机可读存储介质,这些介质包含用于实现以下结合微处理器或其它数据处理器描述的步骤的指令。当依照此处描述的方法和技术编程时,本发明也包括计算机本身。为说明起见,诸如操作系统等程序和其它可执行程序组件在此被示出为离散的框。然而,可以认识到,这些程序和组件在不同的时刻驻留在计算机的不同存储组件中,且由计算机的数据处理器执行。尽管结合包括计算机130的示例性计算系统环境来描述,然而本发明也可用众多其它通用或专用计算系统环境或配置来操作。该计算系统环境并非对本发明的使用作用域或功能提出任何局限。此外,该计算环境不应当被解释为对示例性操作环境中所示的组件的任一个或其组合具有任何依赖性或要求。可适用于本发明的公知的计算系统、环境和/或配置的示例可包括,但不限于,个人计算机、服务器计算机、手持式或膝上设备、多处理器系统、基于微处理器的系统、机顶盒、可编程消费者电子产品、移动电话、网络PC、小型机、大型计算机、包括上述系统或设备的任一个的分布式计算环境等等。本发明可以在诸如由一个或多个计算机或其它设备执行的程序模块等计算机可执行指令的一般上下文环境中描述。一般而言,程序模块包括但不限于,例程、程序、对象、组件、数据结构等等,它们执行特定的任务或实现特定的抽象数据类型。本发明也可以在分布式计算环境中实践,其中,任务由通过通信网络连接的远程处理设备来执行。在分布式计算环境中,程序模块可以位于包括存储器存储设备的本地和远程计算机存储介质中。软件体系结构上下文中的接口包括软件模块、组件、代码部分或其它计算机可执行指令序列。例如,接口包括访问第二模块的第一模块,以代表该第一模块执行任务。在一个示例中,第一和第二模块包括诸如由操作系统提供的应用程序编程接口(API)、组件对象模型(COM)接口(例如,用于对等应用程序通信)、以及可扩展标记语言元数据互换格式(XMI)的接口(例如,用于web服务之间的通信)。接口可以是紧耦合的同步实现,诸如Java2平台企业版(J2EE)中、COM或分布式COM(DCOM)示例。作为替换或除此之外,接口可以是松耦合的异步实现,诸如web服务中(例如,使用简单对象访问协议)。一般而言,接口包括以下特征的任一组合紧耦合、松耦合、同步和异步。此外,接口可以符合标准协议、专有协议或标准和专有协议的任一组合。此处描述的接口可以都是单个接口的一部分,或可以被实现为单独的接口或其中的任何组合。接口可以本地或远程地执行以提供功能。此外,接口可包括比所示或所描述的更多或更少的功能。此处所示和描述的方法的执行或实现的顺序不是关键的,除非另外指定。即,方法的各元素可以用任何顺序执行,除非另外指定,并且方法可包括比此处所解释的更多或更少的元素。例如,在本发明的范围内可以构想,可以另一元素之前、与其同时或在其之后执行特定元素。当介绍本发明或其实施例的元素时,冠词“一”、“一个”、“该”和“所述”意指存在一个或多个元素。术语“包含”、“包括”或“具有”旨在包括性的,且意味着除所列出的元素之外还可以有其它元素。鉴于以上内容,可以看到,可以实现本发明的若干目标并且可以达到其它有利的结果。由于可以在以上构造、产品和方法中做出各种改变而不脱离本发明的范围,因此预期以上描述中包含且在附图中示出的所有内容都应当在说明性而非限制性的意义上解释。附录A示例性活动及其示例性实现示例性活动包括以下活动Send(发送)、SendRequest(发送请求)、SendResponse(发送响应)、Receive(接收)、ReceiveRequest(接收请求)、ReceiveResponse(接收响应)、Code(代码)、Delay(延迟)、Fault(错误)、Suspend(挂起)、Terminate(终止)、InvokeSchedule(调用进度表)、InvokeSchedules(调用多个进度表)、InvokeWebService(调用web服务)、DotNetEventSource(.NET事件源)、DotNetEventSink(.NET事件宿)、Sequence(顺序)、Parallel(并行)、While、ConditionalBranch(条件分支)、Conditional(条件)、Constrained(约束)、ConstrainedActivityGroup(约束活动组)(CAG)、EventDriven(事件驱动)、Listen(监听)、EventHandlers(事件处理程序)、ExceptionHandler(异常处理程序)、ExceptionHandlers(多个异常处理程序)、Compensate(补偿)、CompensationHandler(补偿处理程序)、Scope(作用域)以及Schedule(进度表)。每一示例性活动具有与其相关联的元数据。元数据由与该活动相关联的序列化器传输到工作流的声明性表示。例如,元数据可包括可任选的代码分离方法以及可任选的相关集集合。Send活动配合引擎提供用于发送消息的三种活动(例如,Send、SendRequest以及SendResponse),其每一个着重于一个不同的使用情况。另外,由于三个活动共享某一元数据,因此定义了一抽象基类并将其用作所有三个活动的超类。Receive活动配合引擎提供了用于接收消息的三种活动(例如,Receive、ReceiveRequest以及ReeeiveResponse),其每一个着重于一个不同的使用情况。另外,由于三个活动共享某一元数据,因此定义了一抽象基类并将其用作所有三个活动的超类。CodeCode活动执行元数据中指示的代码分离方法。DelayDelay活动执行其强制的代码分离方法来生成DateTime(日期时间)值。它内部地将其实例上的TimeoutValue(超时值)属性设为该值。如果DateTime是过去的,则Delay立即完成。否则,它设置一定时器预定,使得当定时器激发时将通知Delay。当定时器激发时,通知Delay并且它完成。FaultFault活动执行其强制的代码分离方法来生成Exception(异常)对象。它然后抛出该异常。SuspendSuspend活动挂起当前的进度表实例。TerminateTerminate活动终止当前的进度表实例。InvokeScheduleInvokeSchedule活动调用进度表。InvokeWebService通过代理类调用web服务,转递和接收所指定的参数。DotNetEventSink阻断由先前调用的进度表实例引发的指定事件的等待通知。DotNetEventSource引发所指定的事件,并立即完成执行。SequenceSequence活动以有序的方式协调一组子活动的执行,每次一个。ParallelParallel活动并发地执行一组子活动。While迭代地执行子活动。ConditionBranch对每一Sequence语义执行子活动。ConditionalConditional活动包含一组有序的ConditionalBranch活动。Constrained当CAG告知要执行Constrained活动时,它仅仅执行它所包装的活动。CAG(ConstrainedActivityGroup)当CAG执行时,它基于其启用和禁用的约束的评估来执行(并重新执行)子活动。Task对由一个或多个主体执行的工作的外部单元建模。EventDriven包装其执行由“事件”活动触发的活动。Listen条件地执行EventDriven活动的n个子活动之一。EventHandlersEventHandlers活动简单地持有一组EventDriven活动,以供相关联的Scope使用。ExceptionHandler用表示作用域的捕捉块(catchblock)的元数据包装活动。ExceptionHandlers包装一组有序的ExceptionHandler活动。Compensate补偿已完成的子作用域。CompensationHandler包装被定义为用于作用域的补偿处理程序的子活动。Scope作用域是事务边界;异常处理边界;补偿边界;事件处理边界;以及消息、变量、相关集以及通道声明(即,共享数据状态)的边界、Scope内活动的执行是顺序的,并且由此,当构造作用域时,所包含的活动是明确地排序的,如同在Sequence中一样。ScheduleSchedule是配合引擎将执行的唯一顶层活动。CompositeActivities允许控制流的补偿活动类型是Sequence、Parallel、Constrained、ActivityGroup、Conditional、While、Listen。另外,Scope和Schedule是担当容器的补偿活动类型,该容器具有其中的活动的隐含排序。附录B可扩展配合标记语言(XOML)XOML是定义工作流过程定义的示例性声明性标记语言。XOML使用工作流技术的活动模型描述了过程定义。XOML模式格式不仅限于过程定义,而是也可用于描述使用属性和事件来描述对象的任何任意的对象树。XOML是组件树序列化表示/格式,而非具有固定语法的语言(例如,与BPEL、BPML和WSFL不同)。XOML可用于以可扩展标记语言(XML)形式表示任何任意的对象分层结构,其中,每一对象可按照公用语言例程(CLR)元数据(例如,属性和事件)来描述。XOML模式是可扩展的,因为任何任意对象可以是XOML模式的一部分。基本XOML格式XOML文件是XML文件,其根元素是XomlDocument(XOML文档)对象。XomlDocument包含一个过程定义,它是根活动或给定活动包的过程活动的序列化。以下是XOML文件的示例。XomlDocument∷=ProcessProcess∷={Activity}|ContainerActivity}ContainerActivity∷={Activity}|ContainerActivity}<?xmlversion=″1.0″encoding=″UTF-8″?><XomlDocumentVersion=″1.0″CompileWith=″Schedule1.xoml.cs″xmlns=″System.Workflow.ComponentModel,System.Workflow.ComponentModel″><ScheduleID=″Schedule1″NamespaceName=″WorkflowApplication18″CompileAs=″Schedule″></Schedule></XomlDocument>xmlnsxmlns元属性用于将xml名字空间映射到公用语言例程(CLR)名字空间和程序集信息。在上述示例中,xmlns元属性告知,“XomlDocument”是“System.Workflow.ComponentModel.dll”程序集和“System.Workflow.ComponentModel”名字空间中的类名。用于xmlns的格式是“<名字空间名字>,<完全合格的程序集名>”。使用该信息,加载对应的程序集且分解了程序集中的类型。<XomlDocument>xoml的顶层元素是“XomlDocument”。它用于关联关于过程定义的任何上下文专用信息。例如,CompileWith(用……编译)元属性在设计时将分离代码文件与过程定义相关联。类似地,诸如消息类型、通道类型等其它环境专用信息可与过程定义相关联。<Schedule>进度表(schedule)元素是过程定义的根。在一个实施例中,XomlDocument可以与其相关联的一个Schedule子元素。Schedule是可包含任意数量的子活动的合成活动。在一个实施例中,由XOML表示的组件是配合引擎活动,且具有定义良好的创作时行为。由于XOML是CLR组件序列化,因此其类型系统是基于CLR的而非基于XSD的。XOML包括用于以下的声明性构造-XML名字空间到其它名字空间的映射-声明数据、活动和规则-声明性数据绑定和变换-唯一地标识实体(数据、活动、规则等)-引用实体(内部和外部)-定义活动上的属性用于声明性数据绑定XOML序列化器在由名字空间声明的值指定的目录中寻找XML名字空间定义文件。序列化器在预定义的网络地址搜索定义文件。一个示例性定义文件示出如下。<XmlNamespaceName=″Xoml″><SchemaUri=″http//pageA.net/2003/Xoml/Xoml2003.xsd″/><AssemblyName=″System″Version=″1.0″Locale=″???″/><AssemblyName=″System.Art″Version=″1.0″Locale=″???″/><ClrNamespaceName=″System″/><ClrNamespaceName=″System.Controls″/><ClrNamespaceName=″System.Documents″/><ClrNamespaceName=″System.Shapes″/></XmlNamespace>XOML中的所有元素名都被映射到CLR类型名。基于该元素的XML名字空间,定位对应的CLR名字空间和程序集。例如,在以下示例中,Task1从WorkflowApplication1程序集中加载。<Task1ID=″task11″ExecutionType=″Sequence″xmlns=″WorkflowApplication1,WorkflowApplication1″><TemplateActivityID=″task1Activity1″/></Task1>XOML中的元属性是设置属性。属性可以被设置为1.简单的XML元属性<SuspendErrorString=″Process″/>2.具有串值的复合属性<SuspendTargetSubProcess==″Art.Bar,Art.dll″><ErroeString>Task1</ErrorString></Suspend>3.具有对象作为值的复合属性<Suspend><ErrorString><BindPath=″Art″></Bind></Suspend>在这一情况下,变量名的值“Art”作为参数被传递到Suspend活动。确认基础结构确保变量Art的类型可转换成tpyeof(string)。XOML中的数据可以用多种方法来声明。在一个实施例中,代码类用于将类与活动相关联,且defCode用于声明字段。另一种方法是将DataContext(数据上下文)与活动相关联。如果活动没有定义DataContext,则使用父链中该活动的DataContext。以下是以与活动相关联的XOML声明数据源(DataSource)的一个示例。<ProcessID=″Schedule1″><Process.DataContext><ObjectDataSourcedefID=″art″Type=″Art.Bar,Art.dll″Parameters=″10,20″></ObjectDataSource></Process.DataContext><ReceiveID=″receive1″Message=″*Bind(ObjectSource={foo})″Activation=″True″></Receive></Process>以上示例声明了具有类型为“Art.bar”的名字“art”的Data对象。ObjectDataSource实例通过调用其默认的构造函数,或当指定Parameters(参数)元属性时通过调用最匹配Parameter元属性的值的签名的构造函数创建了由TypeName(类型名)所指的类的新实例。类似于Object数据源,也可定义自定义数据源。该数据源实现了以下示例中的IDataSource接口。interfaceIDataSource{publicvirtualObjectData{get;}}该接口具有Data属性,它让绑定能从数据源项中获得数据。DataSource实现也提供了一种强类型化的属性,它返回数据提供者的本机应用程序编程接口(API)。数据绑定将某些底层数据与一个或多个数据源相关联。XOML也允许在绑定之前变换该数据。数据源可以是任何数据源,诸如CLR对象、数据库、XML文档、web服务消息或实现IDataSource接口的自定义的已定义数据源。活动的任何属性可通过定义数据源和活动的目标属性之间的期望对应性被绑定到任何CLR对象。每一这样的对应性指定-数据源项-到数据源项中适当值的路径-目标活动-目标属性创作对象模型的配合引擎提供了一Bind(绑定)类,它具有多个属性,如Transformer(变换器)、Source(源)和Path(路径)。开发者将Path属性设成指定对象所绑定的数据源中的属性或值的串。开发者将Transformer属性设成实现IDataTransformer接口的任何对象。当数据绑定传播值时,它通过变换器传递该值。变换器检查传入的值,并产生新值作为输出。Source属性引用该绑定的源数据。DataSource(数据源)、ActivitySource(活动源)、DataContextSource(数据上下文源)以及ObjectSource(对象源)元属性设置Bind对象的Source属性。ActivitySource元属性通过提供活动标识符作为ActivitySource元属性的值将源设成活动。DataContextSource元属性将Source设为另一活动的DataContext。ObjectSource元属性指定一对象作为绑定的元。DataSource元属性指定一对象作为绑定的源。有多种句法来指定活动的属性的数据绑定。压缩句法允许开发者不指定复杂属性,而是相反直接在属性本身的值中指定数据绑定声明。绑定对象的参数被指定为用分号分隔的名字值。在以下数据绑定示例中,Receive活动上的Message属性被绑定到过程的数据上下文(DataContext)中定义的msg1对象数据源(ObjectDataSource)。同样,Send活动的Message属性被绑定到{receive1}活动的Message属性。<Process><Process.DataContext><ObjectDataSourcedefName=”msg1”TypeName=″MyPerson,MyAssembly,Version=1.0.0.0,Culture=neutral,PublicKeyToken=0123456789abcdef″Parameters=″Brent,0x30″/></Process.DataContext><ReceiveID=″receive1″Message=″*Bind(Source={msg1})″/><SendID=″send1″Message=″*Bind(ObjectSource={receive1};Path=Message)″>...</Process>XOML中的数据变换是使用数据变换器来完成的。数据变换器是允许值在数据源和目标之间往返传播时从一种形式转换成另一种形式的组件。变换器可用于将值从其内部表示转换成唯一值。变换器也可用作数据类型转换器。变换器基于名为IDataTransfomer的接口,它用于将数据从一种格式转换成另一种。接口的一个示例性定义示出如下。interfaceIDataTransformer{objectTransform(objecto);}数据绑定在将源值传播到目标属性时调用Transform方法。参数“o”是源值。以下示例示出了具有XML输入串的变换,它应用XSLT并将其转换成另一XML格式。publicclassMyTransformerIDataTransformer  {  publicobjectTransform(objecto)  {  StringWritersw=newStringWriter();  XmlTextWriterxmlWriter=newXmlTextWriter(sw);  System.Xml.Xsl.XslTransformtransform=new  System.Xml.Xsl.XslTransform();  transform.Transform(oasIXPathNavigable,newXsltArgumentList(),  xmlWriter);  returnsw.ToString();  }  }为引用XOML中的Transformer,开发者在DataContext中声明Transformer对象,然后在Bind类中引用它。以下示例示出如何在XOML中声明性地变换数据。<?xmlversion=″1.0″encoding=″System-1252″?><XomlDocumentVersion=″1.0″xmlns=″System.Workflow.ComponentModel,System.Workflow.ComponentModel″><Manifest><Name>ApprovalProcess</Name><Version>2.3</Version><Description>ThisisanApprovalProcess</Deseription><Identity>16f46fe4-dd01-468c-a685-0474a3a236ab</Identity></Manifest><ProcessdefClass=″WorkflowApplication2.Schedule1″defID=″Schedule1″defresources=″MyWorkflow″><Process.DataContext><ObjectDataSourcedefName=″msg1″Parameters=″Art″TypeName=″System.String,mscorlib″></ObjectDataSource><TransformerSourcedefName=″MyTransformerReference″TypeName=″MyTransformer″/></Proeess.DataContext><ReceiveID=″receive1″HasTypedChannel=″False″Activation=″False″Message=″*Bind(Source={msg1})″UntypedChannel=″*Bind(Source={channel1})″/><InvokeScheduledefID=″invokeSubProcess″TargetProcess=″Art.Bar,art.dll″><ParameterBindings><ParameterBindingParameterName=″inParameter″Value=″*Bind(Source={msg1};Transformer={MyTransformerReference})″></ParameterBinding><ParameterBindingParameterName=″outParameter″Value=″resArt″></ParameterBinding></ParameterBindings></InvokeSchedule></Process></XomlDocument>本发明支持将C#和VisualBasic(或任何其它启用了CodeDOM的语言)与XOML相关联,以让开发者将自定义应用程序逻辑与工作流过程模型相关联。每一活动可任选地定义其自己的用途以及通过伙伴类的代码关联。某些活动拥有与其相关联的对应的伙伴类(例如,配合引擎Scope),而其它仅具有与其相关联的成员、方法和句柄,作为父活动的伙伴类的一部分。伙伴类是局部类。伙伴类的一些典型使用包括■变量、消息、通道和相关集的声明。■入/出/引用参数的声明。■附加自定义属性的声明。■要发送的消息的准备。■已接收消息的处理。■返回布尔值的代码中表达的规则的实现。■本地定义的变量的操纵。■读活动元数据和实例数据。■写活动实例数据(例如,设置要在工作流中执行的活动上的属性)。■引发事件。■对过程模型的动态修改。■抛出异常伙伴类及其相关联的成员可以是XOML的一部分(作为嵌入的代码)或可以作为单独的代码文件的一部分存在。对应地,存在用于将代码与XOML相关联的两种创作模型嵌入代码和分离代码。嵌入代码模型支持作为XOML的一部分的代码的内联(例如,类似于ASP、DHTML或BPELJ的标记内的代码的横切隔离)、该模式适用于不会太过代码密集型的较小尺寸的应用程序。为启用XOML文件的代码嵌入,存在由不与所有其它过程那样具有实现后的真实代码的编译过程解释的标签和元属性的集合。这些标签在.Definition名字空间中定义(xmlnsdef=Definition)。XOML文件中的每一活动可以与defClass元属性相关联,它指定了与活动相关联的类。同样,defCode可用于添加使用代码的方法和字段。对于代码密集型的工作流应用程序,本发明支持代码分离或代码隔离创作模式,它包括将代码分离文件与XOML文档相关联。代码分离文件包含需要它们的活动(例如,进度表和作用域)的伙伴类。XOML文件使用ReferenceFile(引用文件)元素来引用分离代码。在以上两种创作模式的任一种中,XOML编译器执行代码生成,包括发放与用户可见代码类合并的隐藏局部类,以生成与支持代码类的活动(例如,Root或其它)相关联的唯一类型。XOML文件的本地化本发明包括模式中的defresources以指向包含XOML的同一程序集的.resx或.resources。为引用资源标识符,使用resXXX标签。每一XOML文件可以可任选地与以下相关联文件的一个或多个相关联分离代码、规则描述、角色描述、宿主配置以及活动包清单。XOML文件可通过统一资源标识符(URI)句法来引用以上人为因素。每一XOML文件具有包含文件的Name(名字)、Version(版本)、Identity(身份)和描述的清单。XOML文件的版本独立于程序集,该文件是该程序集的一部分。XOML版本用于文档编制目的。过程版本化、SXS、重定向等真正的执行相关方面从根本上是CLR驱动的。<?xmlversion=″1.0″encoding=″Windows-1252″?><XomlDocumentVersion=″1.0″xmlns=″System.Workflow.ComponentModel,System.Workflow.ComponentModel″><Manifest><Name>ApprovalProcess</Name><Version>2.3</Version><Description>ThisisanApprovalProcess</Description><Identity>16f46fe4-dd01-468c-a685-0474a3a236ab</Identity></Manifest><ProcessdefClass=″WorkflowApplication2.Schedule1″defID=″Schedule1″defresources=″MyWorkflow″>......</Process></XomlDocument>附录CXomlSerializer类与活动相关联的序列化器组件从XomlSerializer(XOML序列化器)继承。XomlSerializer也是活动的默认序列化器组件。它在活动属性上反射,并序列化它们。对于合成活动,默认的序列化器组件是CompositeXomlSerializer(合成XOML序列化器),它除原语Xoml序列化之外还序列化子活动。该类中的函数还可被归类为用于序列化和反序列化xoml文件的公有函数、用于控制对象的序列化的函数、以及用于控制对象的反序列化的函数。序列化/反序列化xoml文件的公有函数publicobjectDeserialize(XmlTextReaderreader)给定XmlTextReader(XML文本读取器)对象,该方法反序列化它,并返回一对象。XmlTextReader指向xml元素。它是反序列化xoml文件的公有方法。publicobjectDeserialize(IDesignerSerializationManagersm,XmlTextReaderreader)给定TextReader(文本读取器)和IDesignerSerializationManager(设计器序列化管理器),该方法反序列化一活动。IDesignerSerializationManager对象可用于向对象提供自定义反序列化器,并且也分解类型。publicvoidSerialize(objectobj,XmlTextWriterwriter)该方法将第一参数中指定的对象序列化成XmlTextWriter(XML文本书写器)对象。publicvoidSerialize(IDesignerSerializationManagersm,objectobj,XmlTextWriterwr);该方法将对象序列化成XmlTextWriter对象。它取另外的设计器序列化管理器对象,该对象可用于分解类型附加物。反序列化对象protectedobjectDeserializeObject(IXomlSerializationManagersm,XmlTextReaderrd);该方法反序列化元素并创建对象。它使用xmlns到CLR名字空间和程序集的映射,以分解对象的类型,然后给予与该类型相关联的序列化器创建该类型的实例的机会。XomlSerializer的CreateInstance(创建实例)方法用于创建对象的实例,它可以在导出类中被覆盖。XmlTextReader必须指向元素节点,否则该方法将抛出异常。该方法在创建对象实例之后调用DeserializeContents(反序列化内容)。protectedvoidDeserializeContents(IXomlSerializationManagersm,objectobj,XmlTextReaderrd);该方法用于反序列化对象的属性和子对象。它取对象和XmlTextReader作为参数。XmlTextReader指向XmlElement(XML元素)节点。它通过元素的所有元属性,并调用序列化器上的DeserializeSimpleProperty()(反序列化简单属性)。DeserializeSimpleProperty可被覆盖以完成属性的自定义反序列化。之后,它通过元素的所有子元素且将它们识别为子对象或属性。在认识到子元素作为属性之后,它在序列化器上调用DeserializeCompoundProperty()(反序列化复合属性),否则它调用DeserializeObject()(反序列化对象)来反序列化子元素,并将返回的对象作为主对象的子对象添加。为将返回的对象作为子对象添加,它调用序列化器上的AddChild()(添加子对象)方法,该方法可被覆盖以实现不同的父-子关系运送。protectedvirtualvoidDeserializeSimpleProperty(IXomlSerializationManagersm,objectobj,XmlTextReaderrd);该方法由DeserializeContents()调用来反序列化简单属性。简单属性是其一部分的对象以及XmlTextReader作为参数传递。XmlTextReader指向元属性。元属性名作为属性名来处理。protectedvirtualvoidDeserializeCompoundProperty(IXomSerializationManagersm,objectobj,PropertyDescriptorpd,XmlTextReaderrd);该方法由DeserializeContents()调用来反序列化复合属性。向其传递对象、属性描述符以及XmlTextReader。XmlTextReader指向XmlElement。属性可以是只读或非只读的。如果属性是只读的,则调用属性上的getter(获取器)方法,它将给予对象(现在是所调用对象上的DeserializeContents)来反序列化对象的内容。如果属性是读写的,则它可能仅有一个且仅一个子元素。反序列化第一子元素,然后在属性上设置返回的对象。序列化对象protectedvoidSerializeObject(IXomlSerializationManagers,objecto,XmlTextWriterwr);调用该方法来序列化对象。向其传递需要被序列化的对象以及要在其上写序列化内容的XmlTextWriter。该方法为对象构造XmlQualifedName(XML合格名),它实际上是对象类型的xml名字空间和类名。xml名字空间是使用对象类型的程序集和名字空间信息来构造的。它写具有该合格名的xml元素的开始,然后调用SerializeContents()(序列化内容)来进一步序列化对象的属性和子对象。并且它调用EndElement(结束元素)来关闭元素。protectedvoidSerializeContents(IXomlSerializationManagers,objecto,XmlTextWriterw);调用该方法来序列化对象的所有属性和子对象。向该方法传递对象和指向Xml元素的XmlTextWriter。它寻找对象的序列化器组件,并调用其上的GetProperties()(获取属性)来获取对象的属性。它寻找属性上的DesignerSerializationVisibility(设计器序列化可见性)元属性,如果可见性被设为Visible(可见),则该属性作为简单属性来处理,且调用SerializeSimpleProperty(序列化简单属性),如果可见性被设为Content(内容),则该属性作为复杂属性来处理,且调用SerializeCompoundProperty()(序列化复合属性),否则如果可见性被设为Hidden(隐藏),则忽略该属性。同样,它检查该属性的DefaultValue(默认值)元属性,如果属性的DefaultValue与属性的值相同,则跳过该属性。它调用对象的序列化器组件上的Getchildren()(获取子对象),以获取所有子对象。它然后使用SerializeObject()序列化所有子对象。protectedvirtualvoidSerializeSimpleProperty(IXomlSerializationManagersm,objectobj,PropertyDescriptorpd,stringparentPropName,XmlTextWriterwr);向该方法传递其属性需要被序列化的对象、属性的PropertyDescriptor(属性描述符)以及XmltextWriter对象。该函数通过使用属性名作为元属性名以及使用属性值作为元属性值来写XmlTextWriter上的xml元属性。protectedvirtualvoidSerializeCompoundProperty(IXomlSerializationManagersm,objectobj,PropertyDescriptorpd,XmlTextWriterwr);该方法用于序列化对象的复合属性。向其传递对象、属性描述符以及XmlTextWriter对象。如果属性是只读的,则它创建元素,并调用由该属性的获取器方法调用返回的对象上的SerializeContents(),否则它写入其名字是属性名的起始元素,并调用由属性的获取器方法调用返回的对象上的SerializeObject()。助手函数protectedvirtualIListGetChildren(objectobj);该方法用于获取对象的子对象。通常,对象使用不同的机制来描述父子关系运送。例如,ICompositeActivity(合成活动)使用Activities属性来编程地指示子对象。不同的序列化器可覆盖该属性,并返回子对象的列表。默认地,这返回<null>值。protectedvirtualPropertyDescriptorCollectionGetProperties(objectobj);该方法用于获取对象的属性。默认地,该方法返回其Browsable(可浏览)元属性被设为真,且DesignerSerializationVisibility元属性不被设为Hidden的属性。对象序列化器组件可覆盖该方法,并控制返回的属性的集合。protectedvirtualvoidAddChild(objectobj,objectchildObj);该方法用于添加父对象的子对象。它反转了GetChildren()。该序列化器组件可控制AddChile()实现的行为。protectedvirtualobjectCreateInstance(Typetype,XmlTextReaderrd);该方法用于创建类型的实例。默认地,它调用Activator.CreateInstance()来创建对象。但是导出的类可使用不同的技术来对其组件类型进行CreateInstance()(创建实例),并且它们可通过使用XmlTextReader对象来传递构造函数上的某些参数。CompositeXomlSerializer类合成Xoml序列化器用于序列化合成活动。它具有从基类覆盖的两个方法,用于反序列化和序列化子活动。  publicclassCompositeActivityXomlSerializerXomlSerializer  {  protectedoverrideIListGetChildren(objectobj)  {  ...argumentchecks  ICompositeActivitycompositeActivity=objasICompositeActivity;  return(IList)compositeActivity.Activities;  }  protectedoverridevoidAddChild(objectobj,objectchildObj)  {  ...argumentchecks  ICompositeActivitycompositeActivity=objasICompositeActivity;  IActivityactivity=childObjasIActivity;  compositeActivity.Activities.Add(activity);  }  }IXomlSerializationManager接口IXomlSerializationManager(XOML序列化管理器)从IDesignerSerializationManager(设计器序列化管理器)类继承。它提供了附加功能以向给予xml的活动类型给予合格名,反之亦然。以下是IXomlSerializationManager的接口定义publicinterfaceIXomlSerializationManagerIDesignerSerializationManager{XmlQualifiedNameGetXmlQualifiedName(Typetype);TypeGetType(XmlQualifiedNamexmlQualifiedName);}序列化错误Xoml序列化器使用IDesignerSerializationManager.ReportError()方法来添加所有的反序列化错误。只要反序列化遇到错误,它只需添加错误对象,但是它不停止反序列化过程,直到且除非xml格式是非法的。XomlSerializer使用XomlSerializerException(XOML序列化器异常)类来报告反序列化错误。  publicclassXomlSerializationExceptionException  {  privateintlineNumber=-1;  privateintcolumnNumber=-1;  publicXomlSerializationException(stringmessage,intline,intcolumn)  base(message)  {  ..  }  publicXomlSerializationException(stringmessage,ExceptioninnerException,int  line,intcolumn)  {  ..<!--SIPO<DPn="44">--><dpn="d44"/>  }  publicXomlSerializationException(stringmessage)  {  }  publicintLineNumber{get;}  publicintLinePosition{get;}  }工作流组件模型也向web服务描述语言(WSDL)格式提供了进度表的序列化。序列化器生成包含进度表中每一分类型的通道的端口的WSDL文档。示例性算法如下。-从参与进度表的所有作用域中取出所有分类型的通道-对每一通道-创建WSDL端口类型-基于通道的接口。-创建WSDL绑定-附加到端口类型。-创建WSDL端口-基于通道名且附加到绑定。-对于通道接口上的每一方法-创建端口类型操作。-创建输入消息(其部分是方法的自变量)。添加到操作。-创建输出消息(部分是方法的返回类型)。添加到操作。-对每一消息部分-创建XSD表示类型。类型映射是使用将一种类型转换成XSD类型的XmlReflectionImporter(XMI反射导入器)类(System.Xml.Serialization名字空间)来完成的。每一DesignTimeType(设计时类型)在它被递交給xml.Serialization之前由RunTimeTypeEmitter(运行时类型发放器)转换成已有占位程序(stubbed)的运行时类型。WsdlOptions(WSDL选项)类配置序列化,并从ISerializerOptions(序列化选项)中导出。示例性属性及其使用在下表D1中示出。表D1-示例性序列化属性WsdlSerializer类执行WSDL序列化。示例性类成员在下表D2中示出。表D2-示例性WsdlSerializer类成员RunTimeTypeEmitter类使用类型构建器将DesignTimeType转换成runtimeType。示例性成员在下表D3中示出。表D3-示例性RunTimeTypeSerializer类成员权利要求1.一种用于创建和编译声明性文件的计算机化的方法,所述声明性文件其中具有多个活动,排列所述多个活动以创建由用户定义的工作流,所述多个活动的每一个具有与其相关联的序列化器和元数据,所述计算机化方法包括接收对应于所述由用户定义的工作流的所述多个活动;标识多个序列化器,所标识的多个序列化器的每一个与所接收的多个活动的至少一个相关联;以及执行所标识的多个序列化器以将所述多个活动的元数据传输到所述工作流的声明性表示,所述元数据定义了与所述多个活动的每一个相关联的功能。2.如权利要求1所述的计算机化的方法,其特征在于,所述元数据包括以下的一个或多个属性、方法以及事件。3.如权利要求1所述的计算机化的方法,其特征在于,所述元数据包括软件代码,并且所述方法还包括从所述工作流的声明性表示中检索所述元数据;编译所述软件代码;以及根据所检索的元数据和所编译的软件代码重新创建所述工作流。4.如权利要求1所述的计算机化的方法,其特征在于,还包括将所传输的元数据映射到一可扩展模式定义名字空间以供确认。5.如权利要求1所述的计算机化的方法,其特征在于,还包括编译所述工作流的声明性表示以创建一可执行文件。6.如权利要求1所述的计算机化的方法,其特征在于,还包括确认所述多个活动的每一个。7.如权利要求1所述的计算机化的方法,其特征在于,还包括将所述元数据与一个或多个数据源相关联。8.如权利要求1所述的计算机化的方法,其特征在于,还包括定义用于与所述多个活动的每一个相关联的声明性数据。9.如权利要求1所述的计算机化的方法,其特征在于,一个或多个计算机可读介质具有用于执行权利要求1所述的方法的计算机可执行指令。10.一个或多个具有用于创建和编译声明性文件的计算机可执行组件的计算机可读介质,所述声明性文件其中具有多个活动,排列所述多个活动以创建由用户定义的工作流,所述多个活动的每一个具有与其相关联的序列化器和元数据,所述组件包括接口组件,用于接收对应于所述由用户定义的工作流的所述多个活动;元数据组件,用于标识多个序列化器,所标识的多个序列化器的每一个与由所述接口组件接收的多个活动的至少一个相关联;以及序列化组件,用于执行由所述元数据组件标识的多个序列化器以将所述多个活动的元数据传输到所述工作流的声明性表示,所述元数据定义了与所述多个活动的每一个相关联的功能。11.如权利要求10所述的计算机可读介质,其特征在于,还包括确认组件,用于将所传输的元数据映射到一可扩展模式定义名字空间以供确认。12.如权利要求10所述的计算机可读介质,其特征在于,所述接口组件包括以下的一个或多个图形用户界面和应用程序编程接口。13.一种用于创建和编译其中具有多个活动的声明性文件的系统,所述系统包括存储器区域,用于储存所述多个活动,排列所述多个活动以创建由用户定义的工作流,所述存储器区域还储存所述多个活动的每一个的序列化器和元数据,所述元数据定义了与所述多个活动的每一个相关联的功能;以及处理器,它被配置成执行计算机可执行指令,用于从所述存储器区域中检索所述多个活动,所述多个活动对应于所述由用户定义的工作流;从所述存储器区域中标识多个序列化器,所标识的多个序列化器中的每一个与所接收的多个活动的至少一个相关联;以及执行所标识的多个序列化器以将所述多个活动的元数据从所述存储器区域传输到所述工作流的声明性表示。14.如权利要求13所述的系统,其特征在于,还包括用于从所述存储器区域中检索多个活动的装置,所述多个活动对应于所述由用户定义的工作流。15.如权利要求13所述的系统,其特征在于,还包括用于从所述存储器区域中标识多个序列化器的装置,所标识的多个序列化器的每一个与所接收的多个活动的至少一个相关联。16.如权利要求13所述的系统,其特征在于,还包括用于执行所标识的多个序列化器以将所述多个活动的元数据从所述存储器区域传输到所述工作流的声明性表示的装置。17.如权利要求13所述的系统,其特征在于,还包括一与所述多个活动的每一个相关联的组件模型,所述组件模型包括用于可视地表示所述活动的图标;与所述元数据相关联的软件代码;以及用于执行所述软件代码的运行时应用程序。18.如权利要求13所述的系统,其特征在于,还包括表示所述工作流的声明性表示的数据结构,所述数据结构包括储存所述工作流的标识信息的清单;以及所述多个活动的列表,所述多个活动的每一个具有与其相关联的属性、方法和事件来定义所述工作流。19.如权利要求18所述的系统,其特征在于,所述属性包括公用语言运行时环境类型。20.如权利要求18所述的系统,其特征在于,所述标识信息包括以下的一个或多个名字、版本、描述和身份。全文摘要通过声明性标记语言来表示一组件化的工作流模型。工作流的每一步骤被建模为具有元数据的活动,该元数据描述该工作流步骤的设计时方面、编译时方面以及运行时方面。用户通过用户界面或应用程序编程接口选择并安排活动来创建工作流。收集与工作流中每一活动相关联的元数据来创建工作流的持久表示。用户通过创作自定义活动来扩展工作流模型。文档编号G06F9/44GK1755722SQ200510103659公开日2006年4月5日申请日期2005年9月1日优先权日2004年10月1日发明者D·K·舒克拉,K·P·瓦莱格瑞普拉,M·梅达申请人:微软公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1