你的位置:首页 > ASP.net教程

[ASP.net教程]基于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 items122           {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 DslActivity164         {165           DslStatement = strDslActivity166         });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 结果展示

运行代码,界面如下: