NetBpm 组织架构(4)

大牛的杰做,赞一个html

转自:NetBPM工做流的架构设计及实现浅析web

 

读前的话:因为本文涉及内容颇多,如有地方读来不很明白,建议先跳过,总体上有个认识后,再回过头来理解。做者认识有限,如有错误,欢迎斧正:)原文地址: NetBPM工做流的架构设计及实现浅析(转载请保留)数据库

NetBPM组件接口

    NetBPM由一系列的组件构成,每个组件都实现一个核心接口(采用Facade Pattern)。不一样组件各自负责的核心功能根据WfMC规范而来。
    NetBPM接口图:apache

 
  1. 为流程开发者提供的接口(Process Developer):该接口负责加载流程定义到NetBpm引擎。首先,流程开发者依照nPdl建立一个流程定义,并将其打包成流程定义压缩包(该包包含一个业务流程的全部信息),而后经过NetBPM Web界面或者是其余方式把流程定义压缩包加载到NetBPM引擎,在加载过程当中流程定义压缩包将会被解析被保存到NetBPM数据库中。
  2. 为用户提供的接口(User):这里用户表示执行流程的人。流程运行主要有2种行为:开始一个流程和执行一个活动(activity)。开始一个流程将建立该流程的一个流程实例,一个流程实例对应流程定义的一次执行。一个流程实例包含了一个或多个并行的flow-of-execution(见flow)。对于处在activity-state(活动节点,见nPdl)的flow,系统必定会指派一个具体的人(或者组)或者第三方来执行活动(activity)。执行活动是Execution Interface的第二种行为。固然了,运转接口还会实现一些其余的方法如获取任务列表,获取有效流程定义列表等。  
  3. 外部IT系统(External IT Systems)和NetBpm引擎之间的接口:外部IT系统能以2种方式实现和NetBPM的交互。
    •  系统发起交互:系统直接和外部IT系统交互。当系统想要触发流程中的某一个action时,它必须使用上面提到的Execution Interface。
    •  流程发起交互:对于流程发起交互这种类型来讲,须要有Interactors。这些Interactors是流程定义的一部分,它包含在流程定义包内(实际上Interactors就是可以访问FlowContext的.NET程序集,也就是咱们后面要说到的包含委托类的程序集合)。Interactors在FlowContext(FLOW运行上下文环境)和外部IT系统之间创建起了通讯渠道。
  4. 组织架构数据(Organisational Datastore)和NetBpm之间的接口:仔细想一想,NetBpm是否是还缺了点什么,没错,那就是组织架构的信息:好比说人、团队、部门、角色等。由于在现实状况中,对于不一样的组织结构,组织架构信息可能被保存在不一样类型的数据库中,如LDAP系统,关系型数据库等。为了让NetBPM可以在一个现实的组织架构中实现快速部署,NetBPM把全部的组织架构信息都汇集在一个组件(Organisation Component)中。这种作法也就是咱们一般说道会话门面模式(Session Façade Pattern),它使得NetBPM访问来自不一样数据源的组织架构信息变得更为简单。

     下面咱们逐步介绍NetBPM的各个组件,下面是NetBpm组件结构图:编程

 

定义组件(Definition Component)

     该组件实现核心接口IDefinitionSessionLocal,用来解析、加载流程定义压缩包,并将其保存到数据库中。此外,它还提供获取某个流程定义,获取全部有效流程定义列表等和流程定义相关的方法。架构

运转组件(Execution Component)

     该组件实现了核心接口IExecutionSessionLocal,它是NetBPM引擎推进核心,如前面如述,它主要实现2个方法:开始一个流程实例(Start ProcessInstance)和执行一个活动(Perform Activity)。另外,它还提供获取用户任务列表,取消流程实例等辅助流程运转的方法。框架

组织架构组件(Organization Component)

     该组件实现接口IOrganisationSessionLocal,它把全部的组织架构信息都汇集在一块儿,包括Users、Groups和Memberships。运转组件在为activitie-state指定执行者时,须要有关user和group的信息。这些信息将以只读模式由组织架构组件向运转组件提供。下面是NetBPM默认的组织架构组织数据模型。在此基础上,咱们能够很方便的实现自定义的适合实际项目需求的组织架构组件,以和咱们的用户数据库或者是LDAP系统相关联。ide

     NOTE:NetBPM源码中实现的只是一个简单的组织架构模型,但它提供了一种思考方向,咱们能够很方便在此基础上进行扩展来实现知足切实需求的自定义组织架构组件:)工具

日志组件(Log Component)

     该组件实现接口ILogSessionLocal,用来记录工做流引擎的操做痕迹,象属性值的更新(如用户提交的表单被上级打回从新填写,那么就会出现屡次表单数据,这就是一种属性更新),委托类的调用状况等都会被记录下来保存到数据库中。单元测试

任务调度组件(scheduler component)

     该组件实现接口ISchedulerSessionLocal,在现实的业务流程中,咱们常常会遇到须要定时触发某个任务的需求,任务调度组件正是做用于此。引擎或者是第三方把须要在某个时刻执行的任务信息(包括任务执行环境、执行时间等)封装成Job保存到数据库中。任务调度组件将按照指定的时间间隔不停的扫描任务表,根据执行时间对比来执行定时到了的Job。

管理监控组件(Admin Component)

     该组件用来对流程定义,流程实例执行状况等进行监控。(源码待完善)下面是NetBpm核心项目在Visual 该组件用来对流程定义,流程实例执行状况等进行监控。(源码待完善)

 下面是NetBPM核心项目在Visual Studio解决方案中的源码结构图,全部组件都包含在Workflow文件夹下,每个文件夹分别对应实现了一个核心组件。
 

 

NetBpm中的几个重要概念

flow

     flow不知道翻译为何好,在JBPM中叫作Token,翻译为令牌,这里咱们就叫作flow吧。它表明activity-states(活动节点,见nPdl)的一个“thread of execution”,至关因而一次流程实例执行过程当中在流程定义模板中的令牌(还真难描述清楚,看下面一块儿理解:))。前面说了,一个流程实例表明一个流程定义的一次执行。以下图所示,流程实例的状态能够当作是一颗flows树。 

      当开始一个流程实例后,在start-state(开始节点,见nPdl,start-state实际上能够看作是一种特殊的activity-state)引擎将自动产生一个名为root的flow。flow中包含了该流程实例的相关信息,如属性值、流程定义信息、flow所在activity-state的执行者等。root flow在遇到fork(分散节点,见nPdl)以前,将更新其带有的实时信息(如执行者、属性值等),这些实时信息随着流程的运转而变化。遇到fork后,根据ForkHandler委托类,root flow将分散成若干(>1个)forked flow(咱们能够把root flow称为这些forked flow的父flow)。如果分散为多个,则此时forked flow将并行运行,父flow则暂时退隐,只至到join(汇聚节点,见nPdl)汇聚,引擎将根据join定义的JoinHandler委托类来肯定激活父flow的机制。

     NOTE:关于fork和join机制,请参考nPdl fork、join小节一块儿理解。

attributes(属性)

     attribute用来表示流程实例中的变量。一个attribute-instance(属性实例,也就是属性值)表明一次流程实例执行过程当中对应属性的实例。属性通常有几种,一种是activity-state(包括start-state)须要用户或者第三方来填写(更新)的属性(通常对应用户Web界面表单上要填写的值),一种是角色对应的属性,还有一些用做标识属性(用来存储某些信息以方便后面的节点运用这些信息处理逻辑判断)。

  1. serializer(属性的序列化): 

    Serializer和HtmlFormatter都是委托类,Serializer负责把属性实例在.NET-Objects和文本两种状态间进行转换,以方便把属性值存入和取出数据库。而Htmlformatter主要用来联系属性值和Web Forms显示时对应的http-text。
  2. attribute的范围:attribute-instances(属性实例)和flow有关。在process-definition(流程定义根节点,见nPdl)节点中定义的attribute和root-flow关联,而在concurrnet-block(并行运行块,见nPdl)中定义的局部attribute实例则和forked flow关联。一个flow可以“看见”和它关联的全部属性以及该flow的父flow的全部属性。

引擎运行时上下文环境(Execution Context)

     

由于图片太大,关于继承IHandlerContext的接口关系图查看点击这里

     ExecutionContext(ExecutionContextImpl类型的对象,咱们暂且翻译为运行时上下文环境:)) 包含了引擎在运行时和流程实例相关的全部有用信息(上文中提到的flowcontext就是一种ExecutionContext),它在委托类(包括流程定义压缩包中程序集中定义的委托类)和流程引擎之间创建起了相互联系的渠道,这是很是关键的。如上面ExectutionContext 类图所示,ExecutionContextImpl实现了下面这些接口:IAssignmentContext、IDecisionContext、IForkContext、IActionContext、IJoinContext、IProcessInvocationContext、ITaskContext,这些接口都是为匹配特定的委托类而设计,它们规范了一种特定的上下文环境,如IActionContext匹配action类型委托类,IDecisionContext匹配DecisionHandler类型委托类等,而ExectutionContext是全部这些特殊的运行时上下文环境的一个综合。当引擎在运转组件把ExectutionContext做为参数传送到具体类型的委托类时(关键:这就是委托类和流程引擎创建联系的方式),ExecutionContext对象将“拆箱”成为特殊的Context,如:把ExecutionContext对象传给action类型的委托类Run()方法时,ExecutionContext对象将拆箱为ActionContext对象以限制其可以调用的方法。

     如“继承自IHandlerContext的接口”图中所示,这些接口都继承了同一个接口IHandlerContext。IHandlerContext是一个规范了最基本的委托类处理上下文环境的接口,实现该接口的继承几口也就都要实现IHandlerContext中定义的方法,固然每一种继承它的特定接口又均可以具备其特定的方法。咱们先看公共接口IHanlderContext类图:如上IHandlerContext接口图所示,这些接口都继承了同一个接口IHandlerContext。IHandlerContext是一个规范了最基本的委托类处理上下文环境的接口,实现该接口继承接口的类也就都实现了IHandlerContext中定义的方法。固然,每一种继承它的特定接口又均可以具备其特定的方法。咱们先看公共接口IHanlderContext类图:

     大多数的方法,咱们从方法名称就能够看出其具体做用了,这里重点介绍下GetAttribute()方法和GetConfiguration()方法,这是咱们在写委托类实现时,要常常用到的2个方法。GetAttribute()用来获取流程实例中的属性值,包括流程前面处理者产生的属性值(如用户填写表单的值)和前面处理引擎事件中设置的表示属性值(注:IActionHandler具备SetAttribute()方法,该方法常常用来标识属性值,供后面程序逻辑用)等。而GetConfiguration()用来获取流程定义中设置的parameter(参数,请nPdlparameter小节)。

     下面再来看几种典型的特定上下文环境接口:

  • IAssignmentContext:为IAssignmentHandler委托类提供引擎上下文环境,该接口定义了获取组织架构信息的方法,具体实现方法见类图。
  • IActionContext:为action提供引擎上下文环境,注意其具备SetAttribute的方法,能够为流程实例中的属性赋值,具体实现方法见类图。
  • IForkContext:为IForkHandler委托类提供引擎上下文环境,它定义了如何从父flow分散forked flow的方法,见类图。
  • IJoinContext:为IJoinHandler委托类提供引擎上下文环境,它定义了获取其余并行flows的方法,见类图。
  • IProcessInvocationContext: 为IProcessInvocationHandler委托提供引擎上下文环境,实现方法见类图。
  • 其余的委托类型上下文环境除了实现基本IHandlerContext方法外,没有特定的方法,请参考IHandlerContext方法。

委托类

     在前面咱们一直提到委托类,那么委托类究竟是什么呢?这里委托的概念指的不是.NET Framework中delegate,这里能够理解它为“委托、代为处理”这样的概念就好。

     NetBPM被设计成通用的流程处理引擎,NetBPM核心执行引擎只负责处理最基本的业务流程逻辑,全部不定的逻辑都被委托给一系列的接口,这些接口称做Delegation Interfaces(委托接口),而实现这些接口的类就是委托类。流程定义约定在什么场合使用什么委托类型,引擎和委托类如何关联也在流程定义中完成。

    为了达到最大的可扩展性,流程开发者在流程定义时能够选择下面任意一种委托类实现方式:

  1. 使用已经在NetBpm引擎中实现的有效的委托类。(具备通用性的委托建议采用这种方式在引擎中定义,以便重用)
  2. 使用自定义的委托类,以.NET程序集的形式经过流程定义压缩包动态加载。

     正是方式2这种形式给NetBPM带来了极大的灵活性,把只适合于某个特定流程的的程序逻辑(这些每每占了大多数)以.NET程序集的形式定义在流程定义压缩包中,NetBpm经过流程定义组件将其解析并保存至数据库。当引擎运转流程须要调用委托类时,引擎利用反射技术实例化出委托类对象,而后利用上文介绍的运行时上下时环境(ExecutionContext)创建起委托类和引擎之间的交互渠道,这真是一个使人兴奋的设计:)

     下面是NetBpm中的委托类型(建议和ExecutionContext一节一块儿理解):

  • AssignmentHandler
           实现接口IAssignmentHandler, 它能够和组织架构中的IT-System相互通讯,用来为activty-state指定执行者。IAssignmentHandler具备惟一的方法SelectActor(IAssignmentContextassignerContext),其中的assignerContext是其和引擎联系的渠道;
  • ActionHandler:实现接口IActionHandler,它用来执行一段流程引擎外完成的程序逻辑,关于action在哪里执行,何时执行等在流程定义中被定义。actions能够被看做一系列流程执行事件的侦听接口,它具备方法Run(IActionContext actionContext),actionContext是它和引擎联系的渠道。
  • DecisionHandler:实现接口IDecisionHandler,它用来选择决定走哪一条transition(边,见nPdl),具备方法Decide(IDecisionContext decisionContext),该方法返回选择要走的边的名称,decisionContext是其和引擎联系的渠道。
  • ForkHandler:实现接口IForkHandler,当执行到fork节点时,Forkhandler用来决定从fork流程的边中哪些边须要“forking”。它具备方法Fork(IForkContext forkContext),forkContext是其和引擎联系的渠道。注:forkhandler能够在同一条边上分散多个forked flow。
  • JoinHandler:实现接口IJoinHandler,当执行到join时,JoinHandler决定是否要激活父flow,它具备方法Join(IJoinContext joinContext),joinContext是其和引擎联系的渠道。
  • Serializer:实现接口ISerializer,具备方法Serialize(Object valueObject)和Deserialize(String text),该委托接口负责用来转换属性值,把属性值在.NET-objects(.NET对象)和text-format(文本)之间转换。其中,text-format(文本)用来存储属性值到数据库中。
  • HtmlFormatter:实现接口IHtmlFormatter,该委托主要用来在属性值和其相对应的web界面元素之间创建联系,同时负责解析web界面元素具备的值。若移植到ASP.NET平台,该接口建议重写。
  • ProcessInvocationHandler:实现接口IProcessInvocationHandler,该委托实现收集子流程的初始化数据、收集处理结果、指定完成子流程后要流入的边等方法,processInvocationContext是其和引擎联系的渠道。

................///////////////////////////.............是否要添加委托类的例子


流程定义版本问题

流程定义的名称与版本

     包含在一个流程定义压缩包中的信息叫作流程定义。NetBpm中,流程是由字段name来区分的,也就是说引擎根据流程的name来判断两个流程是否相等。在流程定义包中不能指定版本,当一个流程定义被引擎加载后,NetBpm将检查是否有该流程定义的旧版本。若是有,NetBpm将自动设置该新加载进来的流程版本为全部存在的旧版本流程定义中最高版本数目基础上加1。

流程执行与版本

     当调用运转组件获取流程定义列表方法时,只能获取到每一个流程的最高版本流程定义。这样作保证了用户老是从最新版本的流程定义开始一个流程实例。当新的流程版本加载到NetBpm时,全部正在运行的旧版本的流程实例将保持在原来流程定义方式下运行。

委托类与版本

     关于版本的另一个方面是委托类。不一样版本流程定义的委托类不是共享的,也就是说每一个流程在执行时只会“看到”它本身流程定义的委托类。 


异常处理机制

     NetBpm做为一个集成平台,当流程运行时,确定会依赖公司不少其余的IT资源,一旦这些依赖致使流程执行时出现错误,NetBpm提供了3种解决机制:

  1. 忽略错误
  2. 把错误日志记录下来(默认采用的机制)
  3. 错误执行回滚操做(rollback)

    执行回滚机制中,流程实例将会被回滚到执行activity以前的状态。若是是对NetBpm 调用Eecution Interface时发生流程错误,全部的流过的transition(边)都会执行回滚。


流程定义元素类图

     关于流程定义的详细状况,参见nPdl

 

 


NetBpm中使用的框架或组件

     NetBpm中用到的框架、组件、工具比较多,它们大都是优秀的开源项目。如Castle,NHibernate,Log4Net, NVelocity,NUnit,NAnt等,不要被这些框架吓倒,实际上,它们仅仅只是“框架”而已:)

IOC容器――Castle

     NetBpm使用了Castle框架,主要用它来实现IOC(控制反转或者说依赖注入),以依赖注入的方式加载核心组件,如DBClassLoader,流程定义组件,运行组件,日志组件,组织架构组件,任务调度组件等。在Web程序启动的时候,根据配置文件,全部的核心组件都将注册到Caslte IOC容器中,之后当须要使用某个组件的时候,只需利用系统提供的ServiceLocator(服务加载工具类)从容器中获取实例便可。另外,在任务调度组件中也有用到Castle的Startable Facility(注:你们把facility理解为注入性质的,对Castle IOC内核容器的功能扩充组件。Castle自己自带实现了一些faciltiy,开发者也能够自定义facility),该facitlity主要用来自动运行程序(这里用来自动间隔扫描任务表,进行任务调度)。

     Castle是.NET平台下一个功能强大的优秀开源框架,关于Castle的更多信息,请看Castle官方网站。另外TerryLee的博客中关于Castle的中文资源也很丰富。

数据持久层―― NHibernate

     NetBpm中NHibernate组件是做为Castle的一个facility存在的,它用来实现NetBpm数据持久层, 并方便的实现了事务支持。关于NHibernate的更多信息,请看NHibernate官方网站,关于NHibernate做为Castle的facility相关请看这里

示例web层――MonoRail

     你们在Demo演示体验的时候,必定很奇怪,没有看到熟悉的.aspx页面,而是.rails页面,为何呢?答案就是NetBPM的Web层采用的是MonoRail框架,而不是咱们熟悉ASP.NET框架。MonoRail是Caslte框架下针对web层编程的一个子框架,它从Ruby Rails获取灵感而来,采用架构清晰分工明确的MVC模式。NetBPM采用的使用NVelocity做为页面解析引擎的MonoRail,它只是对NetBPM核心API的一个Web界面演示示例,用来告诉咱们该怎样从Web层调用NetBpm API。因此,虽然MonoRail有其独到之处,可是在其被普及并有好用工具支持以前,咱们只需简单了解下它的运行机制,用以熟悉web层如何利用NetBpm API,不须要了解它太多。用咱们熟悉的ASP.NET实现Web部分显然是更好的选择:)。关于MonoRail的更多信息,请看这里

系统日志 ――Log4Net

     log4net你们必定不陌生了,NetBpm使用它来记录系统日志,关于log4net的更多信息,请看Log4Net官方网站,网上中文资源也很丰富.

单元测试工具――NUnit

     单元测试工具NUnit一直是你们用来单元测试的利器。 NetBPM源码中已经建有几个测试工程。关于NUnit的更多信息,请看NUnit官方网站

     注:移植到.NET Framework 2.0下,可能要更改其版本。


后记

     NetBPM的设计无疑是巧妙的,可是现阶段的它显然还不是一个完美的工做流引擎,缺少如JBOSS这样的强大后盾做支持,中途又赶上强敌WF,NetBPM远没有其兄弟JBPM风光,更新没有它快(JBPM已经出3.0版本了),获取的支持也少量多, 可是.NET平台下能有这样一个优秀的开源工做流项目是十分难得的,若是您正在WF中苦苦挣扎,也许,开源的NetBPM将带给您一个惊喜:) 

待写:NetBPM工做流nPdl详解,一个NetBPM现实生活中请假审批示例

相关文章
相关标签/搜索