工作流系统中的语法标记系统

以微软的WF为基础,为达到ERP中的批核与通知目的,参考现有系统中的技术,在此分享其中的技巧。

先来看最终的结果,也就是下图中的工作流宿主。

在上面的工作流定义中,除工作流宿主(rehost)技术外,还需要解决规则表达式的解析难题。

.NET WF提供的规则编辑器是基于代码的,但对于一个无代码的开发环境,需要找到一种表达式的设计,解析规范。

比如,在运行时,我们需要根据当前的运行参数解析出以上表达式的分支,最终流向哪个批核结点。

经过摸索,我提供现有系统中已经应用的三种方案,供读者参考。

1 查询表达式

比如一个费用报销流程,当报销金额小于1000元时,可由部门主管直接批核。用SQL语句表达如下:

SELECT AMOUNT  FROM dbo.ICMOVH WHERE AMOUNT <1000
AND REF_NO=‘<%InventoryMovementEntity.RefNo%>‘
 
<% 标记表示当前正在运行的业务对象,<%InventoryMovementEntity.RefNo%> 这一句可取到当前业务对象的标识值。再与金额条件Amount(小于等于1000)组合,当存在这样的单据时,即为满足分支条件,由部门主管批核。
 

2 查询语句

查询语句的作用是为了发送消息通知,将SQL命令通过参数化的方式封装,达到运行时获取数据的目的。
比如一个安全库存报警,当物料安全库存变动时,物料的库存余额小于当前物料设定的安全库存。
 
为了查询数据,设计出一种新语法标记,例子如下:
<%RepeatEachRecord_Begin.SqlQuery1%>
Job No: <%SqlQuery1.job_no%>
<%RepeatEachRecord_End.SqlQuery1%>

通过上图的界面设计中可看出,一个消息通知可包含很多个SQL命名查询,每个SQL命名查询可返回一个或多个数据行,我们在消息文本中用特定的语法,解析出命名查询中字段,即可达到获取数据的目的。

3 常量

工作流中的活动可理解为一个封装的独立的代码片段,为了与外界通信,必须向活动传递参数。有时候参数是固定的值,比如当前的报销单据,在前面我们用到过<%InventoryMovementEntity.RefNo%>表示报销单据编号。

若是要取到当前登录系统的用户,可用<%SessionEntity.UserId%>来获取。

比如给仓库单据增加一个验证,取出当前用户创建的引用(Reference)为空的参考编号。可通过下面的SQL语句实现:

SELECT RefNo  FROM dbo.ICMOVH WHERE REFERENCE IS NULL
AND CREATED_BY=‘<%SessionEntity.UserId%>‘

 

4 调用程序代码

在一套业务工作流系统中调用代码实在是无奈之举。如果发生的业务很有规律,可考虑封装为活动以方便重用。

代码活动的表达方式如下:

我用了三行标记为的是表示一个.NET方法:
assembly=Microsoft.Workflow
class=Microsoft.Workflow.Extension
method=Microsoft.Workflow.Extension.VoucherPost
如果你熟悉.NET反射,很快能写出调用这个方法的代码。
Assembly assembly = null;
Type type = null;
string method = string.Empty;
List<string> format = new List<string>() { "assembly", "class", "method" };
string[] codes = Regex.Split(this.Code, ";");
foreach (string code in codes)
{
   if (string.IsNullOrWhiteSpace(code))
                    continue;

   string[] segments = Regex.Split(code, "=");
   if (Microsoft.Common.Shared.StringCompare(segments[0].ToUpper(), "assembly".ToUpper()) == 0)
         assembly = Assembly.Load(segments[1]);
   if (Microsoft.Common.Shared.StringCompare(segments[0].ToUpper(), "class".ToUpper()) == 0)
         type = assembly.GetType(segments[1]);
   if (Microsoft.Common.Shared.StringCompare(segments[0].ToUpper(), "method".ToUpper()) == 0)
        method = segments[1];
}

type.GetMethod(method, BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
从最后一段代码中可以看出,上面标记的方法必须是静态(static,非实例)方法。
 
最后,我将前三种情况附加到程序中,以帮助对话框的形式提供给工作流开发人员。
 
 
我这里所提到的工作流是以微软的WF为基础开发的一套工作流系统,如果你需要自定义一套工作流设计,业务开发,表达式解析等功能,文中的标记技术可供您参考。
 
时间: 2024-11-15 22:37:46

工作流系统中的语法标记系统的相关文章

Linux 系统中僵尸进程

Linux 系统中僵尸进程 Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动.僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸. 僵尸进程如何产生的? 如果一个进程在其终止的时候,自己就回收所有分配给它的资源,系统就不会产生所谓的僵尸进程了.那么我们说一个进程终止之后,还保留哪些信息?为什么终止之后还需要保留这些信息呢? 一个进程终止的方法很多,进程终止后有些信息对于父进程和内核还是很有用的,例如进程的

OS X 系统中修改webstorm的默认浏览器

大多数人的问题产生于没有找到os x 系统中webstorm的setting选项. 首先要知道再os x系统中,所有的系统偏好设置均以"preference"呈现.在webstorm中,setting选项并不在file中,而是在file左侧Webstorm选项中的preference中. 然后在preference中找到Web Browsers设置默认浏览器,将希望的默认浏览器拖到最上方,并在右下角通过first list 对其进行选择. 应用(Apply)后即可设置成功!

微服务系统中的认证策略

软件安全本身就是个很复杂的问题,由于微服务系统中的每个服务都要处理安全问题,所以在微服务场景下会更复杂.David Borsos在最近的伦敦微服务大会上作了相关内容的演讲,并评估了四种面向微服务系统的身份验证方案. 在传统的单体架构中,单个服务保存所有的用户数据,可以校验用户,并在认证成功后创建HTTP会话.在微服务架构中,用户是在和服务集合交互,每个服务都有可能需要知道请求的用户是谁.一种朴素的解决方案是在微服务系统中应用与单体系统中相同的模式,但是问题就在于如何让所有的服务访问用户的数据.解

系统中《员工管理》设计参考

RDIFramework.NET ━ .NET快速信息化系统开发框架 9.2  员工管理 -Web部分 员工(职员)管理主要是对集团.企事业内部员工进行管理.在后面的章节可以看到有一个用户管理,这两者有什么关系呢?员工包含当前企事业单位的所有职员(如保安.保洁员等),这些员工不一定都需要登录到系统中做相应的业务操作,而用户则是可以登录到系统中进行操作的系统使用者.如果某个职员也可以进行登录,那么我们可以不必要再为其加一条用户信息,可以直接做个映射即可把当前员工(职员)映射为用户. 员工(职员)管

从其它系统登录到SharePoint 2010系统的单点登录

从其它系统登录到SharePoint 2010系统的单点登录 分类: sharepoint2010 2014-03-18 16:28 68人阅读 评论(0) 收藏 举报 转:http://www.tuicool.com/articles/i22Ibu 以前做的只是使用SharePoint的单一登录,用SharePoint去登录其他的系统,现在要反过来,用Form认证的系统来登录SharePoint. 我们都知道,SharePoint使用的是域认证系统,登录到SharePoint系统上,用户必须要

oa办公系统中工作流系统到底有什么作用?

作为当前应用最为广泛的企业管理软件,oa办公系统自有其"过人之处",工作流就是其中之一. 一.工作流是个什么东西? 工作流概念起源于生产组织和办公自动化领域,是针对日常工作中具有固定程序活动而提出的一个概念,目的是通过将工作分解成定义良好的任务或角色,按照一定的规则和过程来执行这些任务并对其进行监控,达到提高工作效率.更好的控制过程. 增强对客户的服务.有效管理业务流程等目的. 二.oa办公系统引入工作流之后会怎样? 在oa办公系统还没有引入工作流这个核心功能时,许多公司采用纸张表单,

Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名

Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf  动态库的后缀为*.so  静态库的后缀为 libxxx.a   ldconfig   目录名 转载自:http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情. 在Linux操作系统中,普遍使用ELF格

Linux系统中“动态库”和“静态库”那点事儿【转】

转自:http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情. 在Linux操作系统中,普遍使用ELF格式作为可执行程序或者程序生成过程中的中间格式.ELF(Executable and Linking Format,可执行连接格式)是UNIX系统实验室(USL)作为应用程序二进制

《深入浅出WPF》学习笔记之系统学习XAML语法

XAML是WPF技术中专门用于设计UI的语言,设计师直接使用XAML设计界面,设计完成后输出XAML代码交给程序员直接使用. XAML是一种由XML派生而来的语言,所以会继承XML中的一些概念. 命名空间: 命名空间为避免标签的名称冲突而出现,可以把来自不同程序集中的类映射到自定义的命名空间前缀,使用语法xmlns[:可选的映射前缀]="名称空间和程序集".没有映射前缀的命名空间为默认命名空间,默认命名空间只能有一个.命名空间映射一般写在根标签上. 标签与运行时对象的关系: 在XAML