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

下面我们创建一个订单明细的窗体,用来修改金额等数据,用来测试业务规则是否正常运行:、

     public partial class FrmOrder : Form
{
public FrmOrder()
{
InitializeComponent();
dgvOrder = this.dataGridView1;
} public DataGridView dgvOrder;
private void FrmOrder_Load(object sender, EventArgs e)
{
this.dataGridView1.Rows.Add(new object[] { "", "p1", "", "", "", "","","01.01" });
this.dataGridView1.Rows.Add(new object[] { "", "p2", "", "", "", "", "", "01.01" }); } private void 保存SToolStripButton_Click(object sender, EventArgs e)
{
this.Hide();
}
}

然后我们定义一个主界面来定义规则和调用处理逻辑:

     using RulesEngine;
using RulesEngine.BooEvaluator;
public partial class Form1 : Form
{ DataGridView dgvOrder = null;
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
this.dataGridView1.Rows.Add(new object[] {"return (订单.金额>200)",@"
订单.折扣=0.9;
订单.审批人=""admin"";
订单.折后金额=订单.金额*订单.折扣;
订单.备注 = ""规则引擎产生"";
return true;" });
this.dataGridView1.Rows.Add(new object[] {"return (订单.金额<=200 且 订单.金额>100)",@"
订单.折扣=0.8;
订单.折后金额=订单.金额*订单.折扣;
订单.备注 = ""规则引擎产生"";
return true;" }); this.dataGridView1.Rows.Add(new object[] {"return (订单.金额<=100 且 订单.金额>0)",@"
订单.折扣=1.0;
订单.折后金额=订单.金额*订单.折扣;
订单.备注 = ""规则引擎产生"";
return true;" }); }
//run
private void 保存SToolStripButton_Click(object sender, EventArgs e)
{ DslRuleTests test = new DslRuleTests();
test.Setup(); //test.EvaluateRules(); var order = test.EvaluateRules(this.dataGridView1, dgvOrder);
this.txtResults.Text = order.ToString(); } private void toolStripButton1_Click(object sender, EventArgs e)
{
FrmOrder frm = new FrmOrder(); frm.ShowDialog(); dgvOrder = frm.dgvOrder;
}
} public class DslRuleTests
{
private BooLangEvaluator evaluator; private List<Emp> listEmp = new List<Emp>(); public void Setup()
{
var dslEngineStorage = new DslEngineStorage(); evaluator = new BooLangEvaluator(dslEngineStorage); listEmp.Add(new Emp { id = "", leader ="" ,name="jack"});
listEmp.Add(new Emp { id = "01.01", leader = "", name = "smith" });
listEmp.Add(new Emp { id = "01.01.01", leader = "01.01", name = "john" }); }
//审批处理
private void SP(Order o)
{ foreach (Emp emp in listEmp)
{
if (emp.id == o.maker)
{
o.wfprocess = emp.leader;
o.wfprocessname = getName(o.wfprocess);
}
} }
//获取职工姓名
private string getName(string id)
{
foreach (Emp emp in listEmp)
{
if (emp.id == id)
{ return emp.name;
}
}
return "";
}
//求和
private void SumAmount(Order o)
{
var sum = o.ItemLists.AsQueryable().Sum(x => x.amount);
o.amount = sum;
}
//解析规则脚本
public Order EvaluateRules(DataGridView dgv,DataGridView dgvOrder)
{
Order order =new Order { memo = "", maker = "01.01", discount = , datetime = DateTime.Now };
order.ItemLists = new List<items>();
foreach (DataGridViewRow dr in dgvOrder.Rows)
{
if (dr.Cells[].Value != null)
{
var item = new items
{
productid = dr.Cells[].Value.ToString(),
productname = dr.Cells[].Value.ToString(),
price = double.Parse(dr.Cells[].Value.ToString()),
num = double.Parse(dr.Cells[].Value.ToString()),
amount = double.Parse(dr.Cells[].Value.ToString()),
discount = double.Parse(dr.Cells[].Value.ToString()),
afteramount = double.Parse(dr.Cells[].Value.ToString()) }; order.ItemLists.Add(item);
}
} SumAmount(order);
SP(order);
string strDslStatement="";
string strDslActivity = "";
EvaluatorAccessPoint.DslConditionEvaluator = evaluator; foreach (DataGridViewRow dr in dgv.Rows)
{ strDslStatement = dr.Cells[].Value.ToString()
.Replace("订单", "this")
.Replace("金额", "amount")
.Replace("且", "and")
.Replace("或", "or");
strDslActivity = dr.Cells[].Value.ToString()
.Replace("折扣", "discount")
.Replace("折后金额", "afteramount")
.Replace("金额", "amount")
.Replace("订单", "this")
.Replace("备注", "memo")
.Replace("审批人", "wfprocessname")
.Replace("且", "and")
.Replace("或", "or"); var conditionRule = new DslCondition { DslStatement = strDslStatement }; var rule = new ActivityRule(conditionRule, new DslActivity
{
DslStatement = strDslActivity
}); var result = rule.Evaluate(order);
if (result)
{
//break;
return order; } }
return null; } }

 4 结果展示

运行代码,界面如下:

基于RulesEngine的业务规则实现的更多相关文章

  1. BizTalk动手实验(九)业务规则引擎使用

    1 课程简介 通过本课程熟悉业务规则引擎(BRE)的使用(本环境为Windows 2008 32位操作系统环境 + Visual Studio 2010 + BizTalk 210) 2 准备工作 1 ...

  2. pfSense配置基于时间的防火墙规则

    基于时间的规则允许防火墙规则在指定的日期和/或时间范围内激活.基于时间的规则与任何其他规则的功能相同,只是它们在预定时间之外的规则集中实际上不存在. 基于时间的规则逻辑处理基于时间的规则时,调度计划确 ...

  3. 理解DDoS防护本质:基于资源较量和规则过滤的智能化系统

    本文由  网易云发布. 随着互联网生态逐渐形成,DDoS防护已经成为互联网企业的刚需要求,网易云安全(易盾)工程师根据DDoS的方方面面,全面总结DDoS的攻防对抗. 1.什么是DDoS DDoS全称 ...

  4. SpringBoot2 整合 Drools规则引擎,实现高效的业务规则

    本文源码:GitHub·点这里 || GitEE·点这里 一.Drools引擎简介 1.基础简介 Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的 ...

  5. (十五)整合 Drools规则引擎,实现高效的业务规则

    整合 Drools规则引擎,实现高效的业务规则 1.Drools引擎简介 1.1 规则语法 2.SpringBoot整合Drools 2.1 项目结构 2.2 核心依赖 2.3 配置文件 3.演示案例 ...

  6. Asp.net 面向接口可扩展框架之业务规则引擎扩展组件

    随着面向接口可扩展框架的继续开发,有些功能开发出现了"瓶颈",有太多的东西要写死才好做.但写死的代码扩展性是非常的不好,迷茫中寻找出入... 进而想到我以前开发的好几个项目,都已有 ...

  7. Dynamics CRM 2015Online Update1 new feature之 通过业务规则清空字段的值

    自2013引入业务规则后很多的功能就不需要通过javascript来实现,业务人员直接通过配置就能解决.那随着版本的更新业务规则的功能也越来越强大,从之前很单纯的逻辑到后面的if..else,相信后面 ...

  8. Dynamics CRM2013 业务规则的新建、激活与删除

    CRM2013的一个新的feature叫做业务规则,一些页面的简单的显示隐藏的控制.字段是否必填.有条件的锁定字段.错误提示等等,以前都是需要些脚本代码实现现在只需通过业务规则做一些简单的配置就可以达 ...

  9. Ckrule业务规则管理系统简介

    1.   简述 Ckrule业务规则管理系统(BRMS)是一个集成的应用程序存储.管理.执行和测试的平台,允许组织定义.部署.监控和维护运营系统使用的各种复杂决策逻辑.Ckrule BRMS 独立于核 ...

随机推荐

  1. 解析大型.NET ERP系统 窗体、查询、报表二次开发

    详细介绍Enterprise Solution 二次开发的流程步骤,主要包括数据输入窗体(Entry Form),查询(Query/Enquiry),报表(Report)三个重要的二次开发项目. 数据 ...

  2. CSS中模拟父元素选择器

    很多情况下,我们需要找到父元素,但可惜的是css中并没有这样的一个选择器. 至于原因可以看张鑫旭的如何在CSS中实现父选择器效果这篇文章. 简单来说这个实现并不是真正的父元素选择器,只是利用其它思路来 ...

  3. 原生JS实现分页效果2.0(新增了上一页和下一页,添加当前元素样式)

    虽然写的很烂,但至少全部都是自己写的,因为这个没有固定的顺序,所以就没有封装,如果你技术好的话,可以你写的分享给我,谢谢. <!DOCTYPE html><html lang=&qu ...

  4. javascript中可变值与不可变值(原始值)

    字符串原始值修改不了1 var str = "abc"; 2 str[0] = "d"; 3 console.log(str[1]="f") ...

  5. 多个Jar包的合并操作

    原文:http://www.cnblogs.com/meteoric_cry/p/4283656.html 需求是将多个jar合并成一个jar的问题.这里列一下操作步骤: 1.将所有jar文件复制至某 ...

  6. java简单词法分析器(源码下载)

    java简单词法分析器 : http://files.cnblogs.com/files/hujunzheng/%E7%AE%80%E5%8D%95%E8%AF%8D%E6%B3%95%E5%88%8 ...

  7. Angularjs中link函数参数含义小节

    restrictE: 表示该directive仅能以element方式使用,即:<my-dialog></my-dialog>A: 表示该directive仅能以attribu ...

  8. Python函数参数默认值的陷阱和原理深究"

    本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...

  9. Quartz应用实践入门案例二(基于java工程)

    在web应用程序中添加定时任务,Quartz的简单介绍可以参看博文<Quartz应用实践入门案例一(基于Web应用)> .其实一旦学会了如何应用开源框架就应该很容易将这中框架应用与自己的任 ...

  10. Cordova webapp实战开发:(6)如何写一个iOS下获取APP版本号的插件?

    上一篇我们学习了如何写一个Andorid下自动更新的插件,我想还有一部分看本系列blog的开发人员希望学习在iOS下如何做插件的吧,那么今天你就可以来看看这篇文字了. 本次练习你能学到的 学习如何获取 ...