• 基于RulesEngine的业务规则实现


      规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。比较常见的业务规则引擎有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 结果展示

    运行代码,界面如下:

  • 相关阅读:
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    配置SpringMVC(两天)
    layui学习4(三天的)动态表格
    layui的学习使用3表单
  • 原文地址:https://www.cnblogs.com/isaboy/p/c_rulesengine_demo.html
Copyright © 2020-2023  润新知