.NET:工作流中如何动态解析路由规则,你肯定用得着

背景

做流程引擎最终避免不了一个问题:如何动态解析路由规则?

几乎所有的审批流程都要求支持条件路由,比如:请假天数大于xx天时某个领导审批,否则其它人审批。常见的解决方法有:一、动态编译;二、解释执行。这篇文章就讲解如何使用Javascript引擎解释执行。

思路

静态语言集成动态语言解释器这种模式,在业界已经有很多惯例,如:很多C++开发者都用Lua在运行时修改配置。因为我对Javascript比较熟悉,所以准备搜索一下Javascript的解释器。在NuGet中用Javascript关键字进行搜索,搜索到了第2页就找到了一个解释器,安装一下,准备尝试吧。

实现

代码下载:http://yunpan.cn/Q5jj9D2GKBZGh

几乎我接触的所有解释器引擎提供的API都很相似,所以这里我直接贴代码了。

CondiationCalculator.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 using Jurassic;
 8 
 9 namespace DynamicExpressionStudy
10 {
11     public static class CondiationCalculator
12     {
13         public static bool IsSatisfied(object entity, string expression)
14         {
15             var engine = new ScriptEngine();
16 
17             if (entity != null)
18             {
19                 foreach (var property in entity.GetType().GetProperties())
20                 {
21                     engine.SetGlobalValue(property.Name, property.GetValue(entity));
22                 }
23             }
24 
25             return engine.Evaluate<bool>(expression);
26         }
27 
28         public static bool IsSatisfied(Dictionary<string, object> variables, string expression)
29         {
30             var engine = new ScriptEngine();
31 
32             if (variables != null)
33             {
34                 foreach (var variable in variables)
35                 {
36                     engine.SetGlobalValue(variable.Key, variable.Value);
37                 }
38             }
39 
40             return engine.Evaluate<bool>(expression);
41         }
42     }
43 }

Program.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace DynamicExpressionStudy
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             {
14                 var leave = new Leave
15                 {
16                     LeaveDays = 5,
17                     LeaveType = "病假"
18                 };
19 
20                 var result = CondiationCalculator.IsSatisfied(leave, "LeaveDays>=5 && LeaveType=='病假'");
21 
22                 Console.WriteLine(result);
23             }
24 
25             {
26                 var leave = new Dictionary<string, object>
27                 { 
28                     { "LeaveDays", 5 },
29                     { "LeaveType", "病假" }
30                 };
31 
32                 var result = CondiationCalculator.IsSatisfied(leave, "LeaveDays>=5 && LeaveType=='病假'");
33 
34                 Console.WriteLine(result);
35             }
36         }
37     }
38 
39     public class Leave
40     {
41         public int LeaveDays { get; set; }
42 
43         public string LeaveType { get; set; }
44     }
45 }

执行结果

备注

有朋友会说这种方式是不是速度会比较慢,确实是慢,不过考虑到一次只判断一个单据,还是可以接受的。

如果要求接近C#的速度,可以采用动态编译+缓存动态程序集的方式,我就用过一次。

 

posted on 2013-05-09 06:51  幸福框架  阅读(3221)  评论(26编辑  收藏  举报

导航

我要啦免费统计