RulesEngine 是轻量级.NET规则引擎,适合抽离简单业务规则(如“订单金额>1000打9折”),但不支持复杂状态机或高并发版本控制;需用JSON定义规则,注意属性大小写、RuleName必填及热更新异常处理。

RulesEngine 是什么,它真适合你的业务规则场景吗
RulesEngine 是一个轻量级的 .NET 规则引擎库,核心价值在于把硬编码的 if-else 或 switch 拆出来,用 JSON/YAML 定义规则,运行时动态加载、执行、热更新。但它不是万能的:不支持复杂状态机、没有内置持久化、不处理高并发下的规则版本冲突。如果你只是想把“订单金额 > 1000 打 9 折”这类逻辑抽离,它很合适;如果要实现“用户连续 3 次失败登录后锁定 15 分钟”,就该换 WorkflowCore 或自研状态管理。
直接用 RulesEngine 类加载 JSON 规则并执行
这是最常用、也最容易上手的方式,适用于规则结构稳定、不频繁变更的内部服务。
- 确保安装 NuGet 包:
RulesEngine(注意不是RulesEngine.Core,后者是旧版或镜像) - 规则 JSON 必须放在
rules.json文件中,顶层是数组,每条规则含RuleName、SuccessEvent、RuleExpressionType和Expression -
Expression是 C# 表达式字符串,会通过 Roslyn 编译,所以能访问传入对象的属性和方法,但不能用await、using、本地函数等 - 执行前需构造
RulesEngine.RulesEngine实例,并调用ExecuteRule方法,传入规则名和输入对象
var re = new RulesEngine.RulesEngine(ruleDefinitions, null);
var input = new { Amount = 1200, IsVip = true };
var result = re.ExecuteRule("ApplyDiscount", input);
常见错误:Expression 中写 amount > 1000(小写)但输入对象属性是 Amount(大写),抛出 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException;或者 JSON 缺少 RuleName,导致 ExecuteRule 返回空结果。
用 WorkflowRules 实现多步骤规则链
当单条规则不够,你需要“先校验库存 → 再检查优惠券 → 最后计算运费”这样的顺序流程时,WorkflowRules 就派上用场了。
- 每个 workflow 是一个 JSON 对象,
WorkflowName唯一标识,Rules是按执行顺序排列的规则名数组 - 所有子规则必须已注册到
RulesEngine实例中(即在ruleDefinitions里定义过) - 执行 workflow 用
ExecuteWorkflow,返回IList<ruleresulttree></ruleresulttree>,每个节点对应一步规则的结果 - 如果某步失败(
IsSuccess == false),默认不会中断后续步骤;如需短路,得在规则的Expression里显式 throw 异常,或用RuleAction控制流
性能提示:workflow 不会自动缓存编译后的表达式,高频调用时建议复用同一个 RulesEngine 实例,避免重复解析 JSON 和 Roslyn 编译开销。
集成 IRuleService 实现依赖注入与热重载
在 ASP.NET Core 项目中,硬编码 new RulesEngine 会导致生命周期混乱、配置难统一、规则无法热更新。
- 注册服务时用
AddRulesEngine扩展方法(来自RulesEngine.DependencyInjection包),它会自动注入IRuleService -
IRuleService提供ReloadRulesAsync方法,可监听文件变化或接收 HTTP 请求触发规则重载 - 注意:重载时旧规则实例仍在运行,新请求才走新规则;若需强一致性,得加锁或用版本号控制
- 避免在
Startup.ConfigureServices中直接读取IConfiguration构建规则——此时配置可能未完全加载;应改用IOptionsMonitor<rulesengineoptions></rulesengineoptions>或延迟初始化
容易踩的坑:调用 ReloadRulesAsync 后没 await,导致规则实际未加载成功;或规则 JSON 语法错误,ReloadRulesAsync 抛异常但被静默吞掉,后续执行始终走旧逻辑。
规则热更新看似简单,但真实环境中 JSON 格式错一位、属性名拼错、表达式引用了不存在的方法,都会让整个 workflow 静默失败——建议在 CI 阶段加入 RulesEngine 的规则校验步骤,而不是只靠运行时报错发现。


















