业务工作流平台设计 - 蓝色的天空,朵朵的白云 - 博客园

来源:百度文库 编辑:神马文学网 时间:2024/04/28 23:53:29
业务工作流平台设计(一)
最近正在忙一个应用集成系统的设计,所以有好长时间没有写工作流相关的文章了。不过这期间我们一直没有放弃对WF的探索。功夫不负有心人,我们在工作流的应用上取得了实质性的进展。因为商业目的,这里不能公布源代码。但为了大家的共同提高,我还是要把一些技术上的关键点给以说明。这期间我和同事做了大量研究,在此对他们表示感谢。
让我们很快切入正题。引入工作流的意义大家都很清楚:将不断变化的处理流程独立出来,以降低开发成本、维护成本,或是其它的东西。那么能达到一种什么样的效果,对于我们这些初次使用的人们来讲更多的是良好的期盼,因为对于WF的应用确实不是一件很容易做的事情。在此之间的一系列文章也只是对一些技术点的探索。现在终于可以整合一下了。
这里拿我们的一个实际需要进行阐述。电台、电视台里的稿件审核流程是一件非常严肃的事情,每个台都有自己一套自己的审核流程,即使一个分台可能视稿件的重要程度、紧急程度、稿件内容的不同有不同的审核流程。举例如下:
l  常规审核流程:一级一级的自下往上审核。如编辑审à科组长审à分台审à总台审。
l  终审制:是常规审核流程的一种扩展。即每个环节都有最终审核权。只要该环节认为没有必要让上级(领导)进行审核,则可以进行此操作。
l  跨审:存在这样的情况,流程中的某一环节因为某种原因(可能相关人员请假了)而导致流程无法运行下去。有两种解决方法:一种是通过延时活动在等待一定时间后,自动将活动跳转到下一个处理环节中去,这种方式的缺点是必需等待;另一种操作方式是,下一个要处理环节的相关人员可以直接审核上一个环节所涉及的稿件内容,这种审核方式即跨审是一种更为及时的操作方式。
每一个环节的审核又可能有下面的表决方式:
l  权重值性要求:环节中参与的每一个用户都有一个权重值。当同意权重值之和达到一定期望值后,则该环节通过。或者反对权重值之和达到一定的期望值则认为是未通过审核。
l  角色性要求。如:某一环节要求五个编辑中的三个如果同意则进入下一个环节,如果有两个表示反对则打回。另一个例子:只要有两个副台或一个正台同意则通过,只要有一个副台或一个正台否决则打回。
l  人员性要求。这个相对简单,只要指定可参与的人员列表,及通过人数和否决人数即可。
如何有效地让客户自已去灵活地、随时随地地设计使用这些流程,而不需要工程人员或售后人员的干预是一个非常棘手的问题。客户关心的是流程中有几个环节。如果让用户自己去用IFELSE或WHILE去设计每一个环节的详细内容,则客户很快会否决这套系统,即使是技术熟练的工程人员也会皱眉的,维护成本会大幅的攀升的,而且开发人员还要为工作流设计器中的每一个条件做一些复杂和额外的工作。
理想的情况是这样的。用户所面对的工作流设计器非常简单的:他们可以从工具箱中插入一个活动到到工作流编辑界面中去,每一活动所代表的是一个完整的处理环节,而不是处理环节中的一部分;这就是简化用户设计的关键所在。用户不需要为设计一个具体环节的逻辑而感动头痛,他们所做的只是设置一下与业务相关的活动的属性就可以了。这样设计出来的工作流看起来会非常的直观、简练。
要让用户有这样的用户体验,我们得需要进行大量的工作。其主要内容简列如下。
l  工作流编辑器
l  自定义的审核活动
l  基于工作流的工件维护框架
l  工作流设计管理框架
l  分布式部署的要求
然而要将这些有机的组合在一起,使之在不同的应用系统中进行应用,这就是业务工作流平台的概念了。待续。
业务工作流平台设计(二)
的确正如别人所说的那样,WF只是一个foundation而不是一个platform,如果要实现完整的业务工作流平台支持,就这个平台的实现来讲,从技术上说不是很难,我想微软应该可以实现这一点,也许是下一个版本:)。或许就platform和foundation来讲,微软更看中的是foundation。总之现在的应用还是比较麻烦的事情。
那么在微软没有platform的时候,我们怎样实现这个platform呢?我们先看一个我们遇到的问题:
l  每种业务领域有自己不同的工作流程,这一点比较好解决,我们可以为不同的业务领域放置不同的模板。
l  在同一业务领域中,不同的应用可能会有很大的不同,这一点也可以通过扩展某一业务领域中的模板来进行。
l  如何方便地将应用系统中的数据集成到业务工作流平台中进行处理?这里的数据集成分两个阶段:设计时和运行时。如审核中的角色、用户等信息是在设计时指定的;对所有人员的评审数据进行存储和计算合并是在运行时进行的。所有这些数据的访问都应当由自定义活动来进行(一个相对独立的操作环节)。具体的细节在自定义活动中进行说明。
作为一个平台,上面的内容还是不够的,我会按前面的文章中所说的每一个环节进行说明。待续。
业务工作流平台设计(三)
工作流设计器
一开始接触WF时,我就想WF中的设计器是否可以直接给用户来使用,如果可以的话,那么我们便可以省去了单独开发这种图形操作界面所花的时间了。通过摸索,其中的困难还是挺多的。为此我这前也写了些相关的文章,有关如何在宿主中加载工作流设计器的话题已经在前面的文章中有说明,这里就不再述了。
这里的要说明的重点是如何设计一个通用的最终用户可自行设计的编辑器,也就是说这个编辑器不只是应用于前篇文章所说的新闻系统。这里的技术点在于,每个应用系统都有自己特定的自定义活动,而这个设计器又如何去识别这些自定义活动。对于这个技术点来讲其实现还是比较简单的,那就是用“反射”。
来看一下我们的应用系统会有什么样的要求?
l  由客户自已来设计业务工作流,操作简单、直观,
l  本身可以独立运行,也可作为二次开发的类库。
l  可以是一个独立的窗口,也可以是一个应用于其它窗口的控件。
l  如果是一个独立的编辑器窗口,我们可以设置窗口的标题。
l  可以定制根活动的标题,及相应的提示信息(非常有必要,SequentialWorkflowActivity是英文的:<)。对于如何改变活动的外观请参照前面我写的文章。
l  根活动的外观定制是可选的如,前景、背景、过渡、边框等。对于如何改变活动的外观就参照前面我写的文章。
l  我们设计时使用的活动列表,这些活动我们可以通过反射技术加以呈现。
l  将设计好的工作流导出。有两种方式一个直接生成文件,二是生成流。流可以方便应用系统自己去管理这些设计好的工作流。
l  应用系统可以给出一个设计好的工作流以进行编辑修改。
l  可以方便地修改工作流活动的各种属性,包括自定义活动的自定义属性。
对于这些定制,我们设计了一个配制文件来解决。配制文件示例如下:



工作流设计器



WWFDesigner
Infomedia.WWFDesigner.DefaultSequentialWorkflowActivity
工作流设计器
可以在此放活动
Black
White
White,White
Black



System.Workflow.Activities
System.Workflow.Activities.CodeActivity


System.Workflow.Activities
System.Workflow.Activities.DelayActivity


System.Workflow.Activities
System.Workflow.Activities.IfElseActivity


System.Workflow.Activities
System.Workflow.Activities.WhileActivity



这里需要注意的是节,这里我没有给出配制的具体内容,原因是我还没这方面的实现。该节的目的是加载Rules文件,以将设计过程中的条件进行罗列,这样可以方便用户去选择条件表达式。至于条件Rules的生成,我计划是设计一个独立的表达式生成工具(让用户手动去编写这些条件表达式会被骂的^o^)。
这个条件表达式设计器也不是一件很容易的事情。表达式的组成主要有四部分组成:变量、关系运算符(=,!=,),《等)、值、逻辑运算符。其中变量和值是由具体的应用系统来决定的,这就是麻烦所在。还是由配制文件来完成这件事吧,它包含下面的内容:
应用系统中工作流活动所用到的变量列表。
每个变量的类型和取值范围。
条件设计器的产生物是一个XML化的Rules文件,即可将其指定到上面配制文件中的节里。关于条件设计器的实现我这边还没有,如果有谁做了这方面的工作不妨分享一下。
大家可以不必太关心这个条件表达式设计器,至少我这边的项目还没有用到。因为我想我把所有的条件都用到了自定义活动中去了;也就是说工作流设计中不会有象IFELSE\WHILE之类的活动的。
说到自定义活动,请看我下面的文章,待续
业务工作流平台设计(四)
自定义活动(一)
这一小节要讲的东西,目前我认为是最重要的东西。这是业务工作流平台中非常重要的一部分;;也是模板的重要组成部分。我们将从以下几个方面讲述自定义活动:
l  尽可能减少占有时间
l  数据交换
l  锁定处理
l  保持状态的一致性及完整性
l  中止活动的运行
以下是针对自定义审核活动特有的设计
l  功能逻辑的设计
l  回退与重新递交
l  跨审的实现
尽可能减少占有时间
在WWF的一些技术细节与应用体会(一)中我讲过持久化的相关描述,该节虽然不讲技术化的问题,但却与锁定时间有关。所以不得不提SqlWorkflowPersistenceService,它的构造函数里面有一个参数instanceOwnershipDuration用来指定占有的时间。占有的时间过长对于时效性处理是很有害处的。所以我们应当尽量减少instanceOwnershipDuration的值。
在现实生活时每个人的处理速度是不一样的,有的处理的快,有的处理的慢。有的人在处理过程中会去打点水,上个厕所什么的……那么我们究竟要将instanceOwnershipDuration设置为多少才合适?可能很多人会比较难以选择。
其时,我这里是在故意误导大家!一开始的时候我也这么想过。那么有什么方法可以设置到一个比较小的范围(如10s)就可以让所有的处理都可以满足要求。这里有一个现象我得说一下。一个处理过程中计算机所要做的工作有两方面的内容:一是收集用户输入的信息;二是提交数据并进行相应的自动化处理。对于第一点来讲,占用的时间是不可准确估计的,但对于第二点来讲,占用的时间是极其有限的(一般情况下10s足够了)。我想大家可能知道我在说什么了。那就是我们在工作流运行期间不负责处理用户信息的收集。
那么如何做到这一点呢?请看下面的小节。待续
业务工作流平台设计(五)
自定义活动(二)
数据交换
要想使自定义活动能够通用,那么活动所需要的数据来源也必须遵循一定的规范才可以,然而这很难做到。拿自定义审核活动来讲,它可能需要在三个方面的数据(实际还要多):
l  用户设计工作流时指定用于审核的人员列表,指定哪些人可参与这个审核活动。这里有一个技术点,就是如何实现自定义属性编辑器,这里不多讲。
l  工作流实例运行时获得当前用户信息,根据当前用户自定义审核活动可以判断此人是否可以执行此活动,即此人是否在用户列表中存在。如果不可以则中断活动的运行。有关如何中断活动的运行请看后面的文章。
l   活动执行时所需要的数据。业务工作流平台设计(四)中的“尽可能减少占有时间”中讲到将用户数据的收集从工作流中分离出来,以节省占有时间,同时也应将数据同工作流进行分离。工作流不负责这些数据的存储和查询,但自定义审核活动会应用这些数据进行处理以决定该活动是否运行到下一步去;或是继续等待其它用户的审核;或是退回(可经修改再次提交审核);或是不被采用(不能再次提交审核)。
这些数据的获取途径是不确定的,拿用户列表数据来讲,可能是直接访问数据库,也可能是访问Web Service,或是通过配置文件……另外我们是否要求用户采用统一的存储格式。所有这些都是不确定的。那么如何与应用系统进行集成?还是自定义一个接口让应用系统去实现吧。
我们有必要进行这样的隔离,否则这个活动的通用性就会大打折扣。但如果每个活动都有自己不同的数据需要,那么这种情况也是比较繁琐的,最好的方法是集中进行配置。对于每一个设计我们都有一个相应的配置文件,把这些内容放到那里面去我想会是不错的选择。
待续。
业务工作流平台设计(六)
自定义活动(三)
锁定处理
在前面的文章我已经讲过,把用户数据的收集同工作流实例中分离出来。数据的存储也就很可能地进行了分离。这种数据的分离会要求我们去做更多的工作:
l  维护工件(如稿件,任务等要在工作流中进行加工的东西)与工作流实例的关系。我们用WF自带的SqlWorkflowPersistenceService来完成工作流实例的存储。那么工件、工件与WF实例的关系及相关的处理情况应交给应用系统来维护。有关这方面的内容请看后面的“工作流的工件维护框架”。
l  保持工件与WF实例的状态一致性。这部分的解决请后后面的有关“状态一致性”的话题。
l  独占式处理。这是本节的重点内容。
独占式处理,其实处理过程很简单,就是在处理时对数据加把锁,就象进厕所把门锁上一样:)。这里不讲怎样去加锁,而是讲对哪些数据进行加锁以及何时进行加锁。
我们来看一下要完成一个审核活动所要处理的数据
l  对工件进行编辑并进行保存
l  记录工件的审核情况
l  运行完后保存WF实例的状态
其实我们需要锁定的数据只有两个:工件和WF实例。如果工件锁定不成功的话则应退出WF实例的运行,有关如何中止活动的运行,就看后续的文章;如果加锁成功则直到WF实例持久化后再解锁。注意,虽然WF的SqlWorkflowPersistenceService本身有加锁的功能,但还是要等到WF实例持久化后再对工件解锁。
这里有一件事情还要说明。工件在审核过程中可能不会被修改,如果从打开工件时刻开始加锁,则会大大的增加占有时间!切记。我们可以在工件第一次被修改的事件中进行加锁处理,以尽可能地减少占有时间。
讲到这里,细心的人可能发现,工件可能在处理过程中没有被修改,即没有产生加锁信息,此时如果我们运行了WF实例,情况是危险的。我们在进行WF时一定要检测工件是否被锁定了,如果没有锁定则进行加锁,然后再运行WF实例。
先讲到这里,可能有些人嫌我写的太少了,我只能说对不起了,我还有很多的工作要做。待续。
业务工作流平台设计(七)
自定义活动(四)
保持状态的一致性及完整性
上一节讲过,要完成一个审核活动所要处理的数据有下面的内容
l工件进行编辑并进行保存
l记录工件的审核情况
l运行完后保存WF实例的状态
通过上面我们可以看到在工作流活动运行之外我们还进行了一些数据的操作,就自定义审核活动来讲,在WWF的一些技术细节与应用体会(二)中我提到过活动执行的完整性及一些实现方法,在这里是用不上的,因为我们的部分数据在工作流之外进行了处理。我们必须在工作流运行环境之外提供一个将数据的收集、工件的编辑及活动运行后WF实例的持久化放在同一事务中。
另在开发自定义审核活动时我们需要指定PersistOnClose属性。否则这个状态将不会被记录。这个属性非常关键!我们只希望在活动运行完成时自动进行持久化以便使工作流过渡到下一个活动中去。但将条件不满足时,放弃运行(不是中止!)。这对数据的状态一致性也非常重要。
待续……
业务工作流平台设计(八)
自定义活动(五)
中止活动的运行
无论用停止、放弃、中止或中断等之类的这些词都不能很直接地表达我这里所表达的意思!这是目前为止我遇到的封装业务逻辑到自定义活动的最大障碍;因为就自定义审核活动来讲,用户所设计的工作流中每一个活动可能被多次执行。例如需要多个人参与同一个层次的审核,当条件不满足是便“停止”运行,然后等待下一个用户来输入用于计算的基础数据,并重新执行该逻辑,直到条件满足该活动执行完毕并过渡到下一个活动为止。需要特别说明一下,这里的自定义活动的逻辑包含了基础数据的读取,条件的判断及是否往下执行、原地等待还是回退的处理,而不是用一大堆WF预置的活动来支持,全部功能都封装于一个活动之内;另外这里不对回退进行说明,有关回退的内容请看后续的文章。
在WF的SDK中有一个很关键的术语“persistencepoint”,它决定了下次加载时WF实例开始运行的点。我将用这个词语来解释一些问题,让我们来看一下它在我们“中断”工作流中所产生的影响!
我们尝试过多种方法去“中断”WF实例的运行,如:
杀死线程或进程。此方法可以使WF实例被再次加载并重新执行被中断的活动的逻辑。但此方法在实际应用中不可取,有很多的负面影响。
调用WorkflowInstance.Abort。此方法的结果是不确定的,先放着下面会描述。
调用WorkflowInstance.Terminate,此方法行不通,会将WF实例从数据库中清除出去!!!
调用WorkflowInstance.Unload,此方法也行不能,该方法会先进行持久化,然后再“中止”WF实例的运行。因为“persistence point”位于活动的中间逻辑——请求“中断”的后面,所以导致WF实例不能加载运行!!!
在活动执行逻辑内部产生异常,此方法我们是没有成功过,最终结果也是将WF实例从数据库中清除出去!!!
大家已经知道突破点在于Abort上,但这个也被我们差一点放弃,具体的过程已经想不太清楚了,好象是在活动执行逻辑中不能直接调用WF实例的Abort方法,只能由引擎来进行此处理才可以。如何将活动的控制权微妙地转交到引擎上去,我的同事许道松花了一些工夫:)。解决的方法是在活动执行逻辑中返回Executing状态,这样就会触发引擎的OnIdel事件,然后在引擎的OnIdel事件处理中调用WF实例的Abort方法。然而问题不是到此就结束了。
我们用SqlWorkflowPersistenceService来进行我们的持久化工作,在它的构造函数里有一个unloadOnIdle参数,就是这个参数给我们带来了不小的麻烦。如果该参数为真,则会在引擎的OnIdel事件中调用WF实例的Unload方法,这样就会形成一个脏的“persistence point”。所以必须将该参数置为False。
至此同一个活动可重复执行的问题得到了解决。至此自定义活动的话题也将结束。下面将针对自定义审核活动特有的设计进行说明,待续!
业务工作流平台设计(九)
自定义审核活动
前面已经讲了许多有关自定义活动在设计上需要注意的一些事项,但对于自定义审核活动来讲,我们的设计还要有许多工作要进行。
为了简化用户的流程上的设计将流程的一些算法封装到自定义活动中可以大大增加自定义活动的使用的方便性。其直接的效果是从数十个活动减少到三四个,当然这只是针对电台文稿审核来讲的。而且基本上从根本上杜绝了IFELSE、WHILE等活动的使用,这可将用户条件编辑的复杂度降为0!这种设计所带来的另一个好处就是外界应用和工作流交互的灵活性。
可能看过本系列文章中的第一篇的都还有些印象,那里面描述了新闻文稿审核的一些用户需求,如果不太清楚,大家不妨回头看一下,这里不多讲。
审核活动的两种计算模式:
l  人员数量要求。某一条件必须要有一定人员数量的参与要求。
l  权重值和要求。当某一条件的参与人员的权重值之和要达到某一数值。
两种模式中只能在一个活动实例中选择一种模式进行使用,
每种计算模式又都有下面三种类型的载体。
l  角色:可指定多个角色, 且如果在权重值和模式下角色中的每个人的权重值应来源于角色的权重值。或在人员数量要求模式下可以指定总的人员数量要求及每个角色的人员数量要求。
l  人员:可指定参与的人员列表,可有人员数量要求或权重值要求。
l  用户组:和角色的要求类似
每种计算模式中只能使用一种载体,
在现实情况下这些已经足够了。其它许多复杂的情况都可以分解为多个简单的活动实例来处理;这样在程序逻辑和业务管理上都是相对简单和高效的。
自定义审核活动有三个条件:
l  通过条件:满足该条件后,活动便可顺利执行完成。
l  回退条件:满足该条件后,该过程处理起来有一点复杂,下面会讲。
l  不通过条件:满足该条件后,则立即结束WF实例的运行,并从数据库中进行清除。
有人担心这三个条件会在运行时,同时满足。情况有可能是这样的,这主要是因为处理过程中没有锁定和保持状态的一致性所引起的。这个锁定不是简单的WF实例加载时的锁定,而是用于活动处理的数据收集同WF实例的联合锁定及状态持久化。
关于用户数据的收集同实例的运行进行分离并放在同一事务中保持状态的一致性及运用锁定机制和尽量减少锁定时间等话题请参阅前面的文章。
但是还是会有糟糕的事情发生,那就是所有的条件都不可能满足!这不是程序逻辑的功能所引起的问题,而是业务逻辑的问题。这种问题是程序无法去控制的。举个例子:如在设计时要求的人员数量大于实际的人员数量就会发生这种问题。
有关用户系统中的数据
首先我不喜欢这里所谈的问题,它涉及到自定义审核活动的通用性。自定义审核活动在设计时需要指定上面所讲的一系列属性。对于计算模式和三个条件设置来讲是比较简单的,问题出在载体上。“用户、用户组、角色”这些数据的存储与提取会因具体应用而有所不同;包括运行时审核数据的提取都是一个紧耦合的问题。如果要进行松耦合,这里必须要进行相应的映射和转换处理才可以。这会对部署和二次开发带来额外的要求!
但这是值得的,为此我们需要强制定义数据的形态(:)类型)以接收标准的数据(相对于自定义审核活动来讲)。而由应用来做数据的提取与转换。需要说明的是,仅“用户、用户组、角色”的定义还是不够的,在运行时我们还需要把用户的审核信息也必须加以定义才可以。
对实例进行监视及警告
我们不能要求用户所设计的业务逻辑是没有问题的,我们也无法去阻止这种错误的发生,但我们应该有一个监视机制来提醒用户那些WF实例已经好久没有处理了。可以用WF自带的Track&Trace来实现记录WF实例运行的细节。但个人认为那样会产生很多的无用数据,而且要进行清理维护操作。其实有一种更简捷的方法来找出这些停滞了的WF实例:用户审核数据。这些数据包括用户信息,用户的审核意见及所对应的WF设计ID和自定义审核活动ID(需要单独的表来维系WF设计ID和自定义审核活动ID与审核数据的关系)。利用这些数据做一个查询窗口就可以找到“死掉”的WF实例。并给用户提供一个真正杀死WF实例的机会。
Level变量
这是自定义审核活动的一个公共变量,这个变量具有重要意义,它是实现回退处理、再提交、跨审的关键点。如何利用Level变量去实现这些功能先放一下。为了便于后面的理解,先讲一下Level的规则。
每一个自定义审核活动都有一个Level变量。且在设计时,进行指定。Level的值必须是一个整数值。后一个活动实例的Level值必须是前一个活动Level值与1的和。我们必须在WF设计时进行这种Level值的验证,否则上一段所提到的要实现的功能将无法正常工作!
在自定义审核活动之外我们还需要维系一个关系表,这个表包含下面的主要信息:
l  WF实例ID
l  下一个自定义审核活动的Level值,会将该值传递给WF实例中的CurrentLevel变量。
l  工件ID
记住,WF设计图里面没有IFELSE、WHILE和其它非自定义审核活动。有了这张表会方便提取针对某一用户所需要运行的WF实例列表。
回退处理与再提交
WF自定义审核活动实例在运行过程中如果发现满足了回退条件,则活动会创建一个新的WF实例并将Level的值减1赋给新的WF实例并结束清除当前WF实例。不过这里有一个前提条件:只有所在的活动位于第二层或以上,才可以有回退的功能。这样处理后,前一级已经审核处理过的人员就又可以再次进行审核操作了。
这里有以下几个设计要点:
l  回退会创建新的WF实例。这可能是大家都没有想到的事情,其实这就是利用Level属性来简化这种WF设计时的工作精髓所在。从而使设计者不去关心如何在设计界面上“画出”各层之间的复杂的流转关系;而只是关心有几层,并在每层上设计相关的属性便可以了。
l  用户的审核数据必须区分不同WF实例,而不是用稿件进行区分。
l  一个稿件可以有多个WF实例与之关联
有人可能存在疑虑,一个WF实例被分成多次运行会造成数据的切割现象,其实这个问题可以这样来理解。我们用WF的目的是用它的流程“控制”而不是去注重“数据的连续”,数据的连续性其实已经由用户审核数据实现了,所以可以不必关心跨多个WF实例的问题。
跨审的实现
跨审的实现也是借助于Level属性值来工作的。只要所对应的Level值高的用户就可以提调比当前自定义审核活动Level值低的WF实例来运行。只是在运行时将其Level的值设置成该用户所对应的活动的Level值便可以了。
自定义审核活动有这么一个逻辑处理:如果当前WF实例的Level值大于当前活动的Level值则该活动直接运行完毕,以过渡到下一个活动中去;直到Level值相等时再进行审核的业务操作。
自定义审核活动与外界数据的交换
Level是如何被改变的,这可能是大家关心的问题。在这里我们有多种方案可进行选择。
l  静态成员的访问:我们可以把要交换的数据放到一个静态成员变量中。
l  AddService:WFRunTime(对不起,我简写了)和Host是运行在两个不同的线程中的。但WFRunTime有一个AddService的函数可以把Host中的任何东西加入到WF所在环境中去。这样WF实例可以通过GetService来得到该对象。
l  创建实例时指定参数:这个方法只能在创建时进行参数的传递,但对于多次加载的WF实例是无法重新指定这些参数的。
l  communication services interfaces:这是WF SDK里面的东西。主要用于事件和方法,所以最好不要用。
对于Level来讲回退里可用指定的Level来创建新的WF实例;对于跨审和其它情况来讲,则在实例运行前利用第一、二两点的任何一种方法对其实例的Level进行赋值,然后再运行。
其它问题
就现在的情况来看,用户在设计时不需要复杂的设计就可以定制一个“复杂”的审核处理流程。包括逐级递审,回退、跨审等。但这都是人为干预的审核,对于自动审核来讲还是不完善的。自动审核(不是智能审核稿件内容)是指在一定时间内如果没有人为给出审核意见,则自动递交到下一个审核层次上去。这样我们就会相中Delay活动。
如果用Delay就会用到Listen。这会带来一个新的问题!我们的自定义活动必须要有接受外界触发的能力才可以将Delay和我们的审核活动放到Listen中去。如何做?真是两难的选择!我们如果扩展了IActivityEventListener接口,那么我们的审核活动的使用模式便会进行改变!!我不做结论,但很想听一下读者的意见。
写到这里,该结束了。回头看看不觉有些惭愧,平台的东西太少,模板的东西太多。本来还想写一下WF与工件的维护框架,WF设计管理框架。现在看来相对简单,就不写了。如果有什么问题,只要不是基础性的问题,我还是很愿意和大家一起讨论的。
完……。