.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#的速度,可以采用動態編譯+緩存動態程序集的方式,我就用過一次。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM