NxBRE( 规则引擎) 的基本帮助





5.00/5 (7投票s)
这里是 NxBRE(
引言
在本文中,我们将探讨如何在不重新编译代码的情况下,将动态业务规则应用于应用程序。
背景
我的公司需要构建一个 ETL,我的职责是负责“T”部分。
你可以在这里找到关于 NxBRE DLL 的简要介绍:http://sourceforge.net/projects/nxbre/。正如我所说,我不是规则引擎方面的专家,但这个项目可能会帮助你。
在你的应用程序中实现 BRE 是一件好事,你将代码和编写业务规则的智慧将加速你的应用程序,否则可能会影响性能。
使用代码
你需要 VS 2010,这个项目将向你展示一个关于员工税收和 DA 计算的简单演示,具体取决于他们的基本工资。这是包含规则的 XBRE 文件
<?xml version="1.0" encoding="UTF-8"?>
<xBusinessRules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xBusinessRules.xsd">
<Decimal id ="Tax" value ="10"/>
<Decimal id ="DAp" value ="10"/>
<Decimal id="5000" value="5000"/>
<Decimal id="10000" value="10000"/>
<Decimal id="15000" value="15000"/>
<Decimal id="20000" value="20000"/>
<Decimal id="30000" value="30000"/>
<Decimal id="100000" value="100000"/>
<!-- Calculation Of Tax -->
<ObjectLookup id ="EmpObj" objectId ="EmpTexCal" member ="BasicSalary"/>
<Logic>
<If>
<And>
<Between leftId ="5000" rightId ="10000" valueId ="EmpObj">
</Between>
</And>
<Do>
<Modify id ="Tax" type="Decimal" value ="11.5"/>
</Do>
</If>
<ElseIf>
<And>
<Between leftId ="10000" rightId ="15000"
valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="Tax" type="Decimal" value ="13.5"/>
</Do>
</ElseIf>
<ElseIf>
<And>
<Between leftId ="15000" rightId ="20000"
valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="Tax" type="Decimal" value ="14.5"/>
</Do>
</ElseIf>
<ElseIf>
<And>
<Between leftId ="20000" rightId ="30000"
valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="Tax" type="Decimal" value ="15.5"/>
</Do>
</ElseIf>
<ElseIf>
<And>
<Between leftId ="30000" rightId ="100000"
valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="Tax" type="Decimal" value ="17"/>
</Do>
</ElseIf>
</Logic>
<!-- <ObjectLookup id ="EmpObjOut"
objectId ="EmpTexCal" member ="TaxPercentage">
<Argument valueId="Tax"/>
</ObjectLookup> -->
<!-- Calculation Of DA -->
<Logic>
<If>
<And>
<Between leftId ="5000" rightId ="10000" valueId ="EmpObj">
</Between>
</And>
<Do>
<Modify id ="DAp" type="Decimal" value ="25"/>
</Do>
</If>
<ElseIf>
<And>
<Between leftId ="10000" rightId ="15000" valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="DAp" type="Decimal" value ="30"/>
</Do>
</ElseIf>
<ElseIf>
<And>
<Between leftId ="15000" rightId ="20000" valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="DAp" type="Decimal" value ="40"/>
</Do>
</ElseIf>
<ElseIf>
<And>
<Between leftId ="20000" rightId ="30000" valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="DAp" type="Decimal" value ="50"/>
</Do>
</ElseIf>
<ElseIf>
<And>
<Between leftId ="30000" rightId ="100000" valueId ="EmpObj" excludeLeft ="true">
</Between>
</And>
<Do>
<Modify id ="DAp" type="Decimal" value ="60"/>
</Do>
</ElseIf>
</Logic>
<!-- Example Of Evaluation -->
<ObjectLookup id="ExpDAp" type="NxBRE.Imp.Util.Evaluator,NxBRE.Imp" member="CreateExpression">
<Argument value="(" />
<Argument valueId="EmpObj" />
<Argument value="/" />
<Argument value="100" />
<Argument value=")" />
<Argument value="*" />
<Argument valueId="DAp" />
</ObjectLookup>
<ObjectLookup id="EvalDAp" type="NxBRE.Util.Compilation" member="Evaluate">
<Argument valueId="ExpDAp" />
</ObjectLookup>
<ObjectLookup id="CastDAp" type="NxBRE.Imp.Util.Casting,NxBRE.Imp" member="CastData">
<Argument valueId="EvalDAp" />
<Argument value="System.Decimal" />
</ObjectLookup>
<ObjectLookup id ="EmpObjOut" objectId ="EmpTexCal" member ="DA">
<Argument valueId="CastDAp"/>
</ObjectLookup>
</xBusinessRules>
以下是如何读取 XBRE 文件,我稍后会解释 XBRE 文件
public ReadRule(string RuleFilePath)
{
_FilePath = RuleFilePath;
StringBuilder sb=new StringBuilder(255);
if (GetShortPathName(_FilePath, sb, sb.Capacity) != 0)
_factory = new BREFactoryConsole(_engineTraceLevel, _ruleBaseTraceLevel).NewBRE(new XBusinessRulesFileDriver(sb.ToString()));
}
你可以更改跟踪级别以获取跟踪结果。我关注两个方面:一个是读取文件中的规则,另一个是为依赖计算设置值。
设置依赖变量的值。设置特定对象的值。
public void SetObjectRefrance(ReadRule objRule, string ObjectId, object Obj)
{
if (objRule.IsValidXML)
{
if (objRule.IsProcessed)
objRule.Reset();
objRule.Factory.RuleContext.SetObject(ObjectId, Obj);
}
}
我们可以设置任何类型的 ExecuteRuleDelegate
委托,通过它可以我们在执行规则时回调我们的基础代码。
public void SetDelegateRefrance(ReadRule objRule, string ObjectId, ExecuteRuleDelegate Delegate)
{
if (objRule.IsValidXML)
{
if (objRule.IsProcessed)
objRule.Reset();
objRule.Factory.RuleContext.SetFactory(ObjectId, new BRERuleFactory(Delegate));
}
}
在这个规则引擎中,我们可以拆分我们的规则关注点并执行部分规则,或者我们可以执行规则但仅获取部分结果值。
* 我们必须设置依赖值或委托。
public object GetRuleResult(ReadRule objRule, string ObjectId)
{
try
{
if (!objRule.IsProcessed)
objRule.ProcessRules();
return objRule.Factory.RuleContext.GetResult(ObjectId).Result;
}
catch (Exception)
{
}
return FlagResualt.NoProcessed;
}
现在我创建了一个组合函数,它将处理所有上述功能
public void EvaluateRule(ReadRule objRule, RuleRefrance[] RulesReferances,
RuleDelegate[] RulesDelegates, RuleResualt[] RuleReply)
{
if (RulesReferances != null)
AddObjects(objRule, 0, RulesReferances);
if (RulesDelegates != null)
AddDelegates(objRule, 0, RulesDelegates);
// Process Rules
if (!objRule.IsProcessed)
objRule.ProcessRules();
//if (RuleReply != null)
GetObjectResult(objRule, 0, RuleReply);
}
GetObjectResult
只是使用反射在我们的 ORM 或任何其他类中设置值。
现在如何调用所有这些并获取规则输出,这非常简单