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

    本月7日去了一趟链家网面试,虽然没有面上,但仍有不少收获,在此做个简单的分享,当然了主要是分享给自己,让大家见笑了.因为这次是第一次面试JAVA网站架构师相关的职位,还是有些心虚的,毕竟之前大部分时间 ...

  2. 一直都在说反射很有用 谈谈大型.NET ERP系统有哪些地方用到了反射

    反射Reflection,MFC时代叫RTTI(Runtime Type Identification) 运行时类型识别,提供一种动态创建对象的能力. 这里不谈反射的概念和基本用法,仅仅就我遇到的ER ...

  3. CentOS6.5使用createrepo搭建本地源

    本地搭建本地yum源采用的rpm全部来自CentOS-6.5-bin-DVD1&DVD2; 我的是在虚拟机环境安装,先检查我的操作系统版本: 1 2 3 4 [adam@ultraera ~] ...

  4. opcode的执行

    原文链接:http://www.orlion.ga/1001/ 当.php文件被编译为opcode后,下一步的执行并非是把opcode编译为机器码而是类似于如下的方式执行: while (TRUE)  ...

  5. 栈-java代码

    import java.util.Arrays; public class StackDemo { private int maxSize; private long[] stackArray; pr ...

  6. Tmux - Linux从业者必备利器

    本文详细介绍tmux的概念和搭建过程 本博客已经迁移至: http://cenalulu.github.io/ 为了更好的体验,请通过此链接阅读: http://cenalulu.github.io/ ...

  7. Yii的学习(3)--查询生成器 (Query Builder)

    原文地址:http://www.yiiframework.com/doc/guide/1.1/en/database.query-builder 不过原文是英文的,Yii的官网没有翻译这一章,自己就尝 ...

  8. apache解析多个域名

    之前搭建了一个网站在这台服务器上,今天心血来潮准备搭建个word press 博客,准备使用二级域名 blog.xdlxb.cn 来解析. 只需要设置httpd.conf 文件就可以了 如下 开启重定 ...

  9. Eclipse10个最有用的快捷键[From: Internet]

    1. ctrl+shift+r:打开资源这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.xml ...

  10. SQL Server代理(4/12):配置数据库邮件

    SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 在以前的文章里我们看到,SQL Serve ...