基於RulesEngine的業務規則實現

来源:http://www.cnblogs.com/isaboy/archive/2016/03/11/c_rulesengine_demo.html
-Advertisement-
Play Games

規則引擎由推理引擎發展而來,是一種嵌入在應用程式中的組件,實現了將業務決策從應用程式代碼中分離出來,並使用預定義的語義模塊編寫業務決策。接受數據輸入,解釋業務規則,並根據業務規則做出業務決策。比較常見的業務規則引擎有Drools、VisualRules 和iLog。這裡介紹另外一個C#開源工具Rul


  規則引擎由推理引擎發展而來,是一種嵌入在應用程式中的組件,實現了將業務決策從應用程式代碼中分離出來,並使用預定義的語義模塊編寫業務決策。接受數據輸入,解釋業務規則,並根據業務規則做出業務決策。比較常見的業務規則引擎有Drools、VisualRules 和iLog。這裡介紹另外一個C#開源工具RulesEngine。下麵通過一個例子來他如何使用。

1 項目結構

在RulesEngine源代碼中添加一個RulesEngineDemo的窗體應用程式,然後引用需要的類庫,如下圖所示:

2 訂單等實體類定義

這裡用訂單的場景來用規則引擎處理折扣的業務邏輯:

    public class Order
    {
        public double amount;
        public double num;
        public double discount;
        public double afteramount;
        public DateTime datetime;
        public List<items> ItemLists;
        public string maker;//購買人
        public string wfprocess;//審批人
        public string wfprocessname;//審批人
        public string memo;//備註

        public override string ToString()
        {
            string res = string.Format("折扣={0},金額={1},審批人={2}({4}),折後金額={3}", discount, amount, wfprocess, afteramount,wfprocessname);
            return res;
        }
    }
    //用戶
    public class Emp
    {
        public string id;
        public string leader;
        public string name;
    }
    //明細
    public class items
    {
        public string productid;
        public string productname;
        public double price;
        public double num;
        public double discount;
        public double amount;
        public double afteramount;

    }

 3 窗體定義

下麵我們創建一個訂單明細的窗體,用來修改金額等數據,用來測試業務規則是否正常運行:、

 1     public partial class FrmOrder : Form
 2     {
 3         public FrmOrder()
 4         {
 5             InitializeComponent();
 6             dgvOrder = this.dataGridView1;
 7         }
 8 
 9         public DataGridView dgvOrder;
10         private void FrmOrder_Load(object sender, EventArgs e)
11         {
12             this.dataGridView1.Rows.Add(new object[] { "1", "p1", "20", "10", "200", "1","200","01.01" });
13             this.dataGridView1.Rows.Add(new object[] { "2", "p2", "1", "8", "8", "1", "8", "01.01" });
14 
15         }
16 
17         private void 保存SToolStripButton_Click(object sender, EventArgs e)
18         {
19             this.Hide();
20         }
21     }

然後我們定義一個主界面來定義規則和調用處理邏輯:

  1     using RulesEngine;
  2     using RulesEngine.BooEvaluator;
  3     public partial class Form1 : Form
  4     {
  5 
  6         DataGridView dgvOrder = null;
  7         public Form1()
  8         {
  9             InitializeComponent();
 10         }
 11 
 12         private void Form1_Load(object sender, EventArgs e)
 13         {
 14             this.dataGridView1.Rows.Add(new object[] {"return (訂單.金額>200)",@"
 15                訂單.折扣=0.9;
 16                訂單.審批人=""admin"";
 17                訂單.折後金額=訂單.金額*訂單.折扣;
 18                訂單.備註 = ""規則引擎產生"";
 19                return true;" });
 20             this.dataGridView1.Rows.Add(new object[] {"return (訂單.金額<=200 且 訂單.金額>100)",@"
 21                訂單.折扣=0.8;
 22                訂單.折後金額=訂單.金額*訂單.折扣;
 23                訂單.備註 = ""規則引擎產生"";
 24                return true;" });
 25 
 26             this.dataGridView1.Rows.Add(new object[] {"return (訂單.金額<=100 且 訂單.金額>0)",@"
 27                訂單.折扣=1.0;
 28                訂單.折後金額=訂單.金額*訂單.折扣;
 29                訂單.備註 = ""規則引擎產生"";
 30                return true;" });
 31 
 32         }
 33         //run
 34         private void 保存SToolStripButton_Click(object sender, EventArgs e)
 35         {
 36            
 37            
 38               DslRuleTests test = new DslRuleTests();
 39               test.Setup();
 40 
 41               //test.EvaluateRules();
 42 
 43               var order = test.EvaluateRules(this.dataGridView1, dgvOrder);
 44               this.txtResults.Text = order.ToString();
 45 
 46           
 47            
 48         }
 49 
 50         private void toolStripButton1_Click(object sender, EventArgs e)
 51         {
 52             FrmOrder frm = new FrmOrder();
 53 
 54             frm.ShowDialog();
 55 
 56             dgvOrder = frm.dgvOrder;
 57         }
 58     }
 59   
 60     public class DslRuleTests
 61     {
 62         private BooLangEvaluator evaluator;
 63 
 64         private List<Emp> listEmp = new List<Emp>();
 65         
 66         public void Setup()
 67         {
 68             var dslEngineStorage = new DslEngineStorage();
 69           
 70             evaluator = new BooLangEvaluator(dslEngineStorage);
 71         
 72             listEmp.Add(new Emp { id = "01", leader ="00" ,name="jack"});
 73             listEmp.Add(new Emp { id = "01.01", leader = "01", name = "smith" });
 74             listEmp.Add(new Emp { id = "01.01.01", leader = "01.01", name = "john" });
 75 
 76          
 77         }
 78         //審批處理
 79         private void SP(Order o)
 80         {
 81            
 82             foreach (Emp emp in listEmp)
 83             {
 84                 if (emp.id == o.maker)
 85                 {
 86                     o.wfprocess = emp.leader;
 87                     o.wfprocessname = getName(o.wfprocess);
 88                 }
 89             }
 90 
 91            
 92         }
 93         //獲取職工姓名
 94         private string getName(string id)
 95         {
 96             foreach (Emp emp in listEmp)
 97             {
 98                 if (emp.id == id)
 99                 {
100 
101                     return emp.name;
102                 }
103             }
104             return "";
105         }
106         //求和
107         private void SumAmount(Order o)
108         {
109             var sum = o.ItemLists.AsQueryable().Sum(x => x.amount);
110             o.amount = sum;
111         }
112         //解析規則腳本
113         public Order EvaluateRules(DataGridView dgv,DataGridView dgvOrder)
114         {
115              Order order =new Order { memo = "", maker = "01.01", discount = 1, datetime = DateTime.Now };
116              order.ItemLists = new List<items>();
117             foreach (DataGridViewRow dr in dgvOrder.Rows)
118             {
119                 if (dr.Cells[0].Value != null)
120                 {
121                     var item = new items
122                     {
123                         productid = dr.Cells[0].Value.ToString(),
124                         productname = dr.Cells[1].Value.ToString(),
125                         price = double.Parse(dr.Cells[2].Value.ToString()),
126                         num = double.Parse(dr.Cells[3].Value.ToString()),
127                         amount = double.Parse(dr.Cells[4].Value.ToString()),
128                         discount = double.Parse(dr.Cells[5].Value.ToString()),
129                         afteramount = double.Parse(dr.Cells[6].Value.ToString())
130 
131                     };
132 
133                     order.ItemLists.Add(item);
134                 }
135             }
136 
137             SumAmount(order);
138             SP(order);
139             string strDslStatement="";
140             string strDslActivity = "";
141             EvaluatorAccessPoint.DslConditionEvaluator = evaluator;
142 
143             foreach (DataGridViewRow dr in dgv.Rows)
144             {
145 
146                 strDslStatement = dr.Cells[0].Value.ToString()
147                 .Replace("訂單", "this")
148                 .Replace("金額", "amount")
149                 .Replace("", "and")
150                 .Replace("", "or");
151                 strDslActivity = dr.Cells[1].Value.ToString()
152                      .Replace("折扣", "discount")
153                      .Replace("折後金額", "afteramount")
154                      .Replace("金額", "amount")
155                      .Replace("訂單", "this")
156                      .Replace("備註", "memo")
157                      .Replace("審批人", "wfprocessname")
158                      .Replace("", "and")
159                      .Replace("", "or");
160 
161                 var conditionRule = new DslCondition { DslStatement = strDslStatement };
162 
163                 var rule = new ActivityRule(conditionRule, new DslActivity
164                 {
165                     DslStatement = strDslActivity
166                 });
167 
168                 var result = rule.Evaluate(order);
169                 if (result)
170                 {
171                     //break;
172                     return order;
173                     
174                 }
175                
176 
177             }
178             return null;
179            
180         }
181 
182     }
View Code

 4 結果展示

運行代碼,界面如下:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 主要使用了Windows API 實現,你可以在你C盤下的system32文件夾中找到user32.dll,函數的說明在MSDN都有,只需要拿名字去搜一下就行 根據視窗的類名和視窗名稱獲取視窗句柄,成功返回一個視窗的句柄,否則返回0: [DllImport("User32.dll", EntryPo
  • Entity Framework Power Tools是一個由EntityFramework開發小組提供的工具,它可以從現有資料庫生成Fluent款式的Code First代碼。 大致來說,這個工具有這樣幾個功能:1) 按照現有資料庫結構,生成Code First POCO class、DbCon
  • 1 <Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}" TargetType="{x:Type ScrollViewer}"> 2 <Setter Property="Focusable" Value="false"/> 3
  • 在.net開發客戶端的時候,一定會遇到用戶沒有安裝.net環境的問題,特別是現在win7,win8,win10多系統並用的時間段,很多開發者使用的是4.5的目標環境,用戶卻是使用win7的系統,這樣勢必會要安裝環境包 可是如果win7的用戶已經安裝4.5的環境呢?那麼用戶是否需要連帶著環境包一起下載
  • NuGet is a Visual Studio extension that makes it easy to install and update third-party libraries and tools in Visual Studio. NuGet is not mandatory f
  • 什麼是通用語言運行時(CLR),簡單來講: CLR是一個支持多種編程語言及多語言互操作,完整的高級虛擬機。 有點拗口,而且不是很有啟發性,但上面的文字是將又大又複雜的CLR的功能歸類以便容易理解的第一步。它從一萬英尺的高度來幫助我們理解CLR的設計目標。從這個高度明瞭CLR之後,我們可以深入其各個組
  • 葡萄城近日與微軟公司達成合作,將Wijmo 產品線的HTML5和JaveScript 控制項融合到微軟Dynamics CRMOnline 2016版中。
  • 隨手記記 先定義下標誌枚舉: 在項目的model文件夾下新建一個IsEnums.cs類 [Flags] public enum ABC {a=1,b=2,c=4, } 然後在HomeController.cs類中引用下model, 用標誌枚舉的好處就是可以進行自由組合,而標誌枚舉里定義每個都是2的N
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...