文章

RulesEngine

什么是RulesEngine

RulesEngine 是微软开源的一个轻量级规则引擎框架,用于在 .NET 应用中执行业务规则。它允许开发者将复杂的业务逻辑从代码中解耦出来,通过定义规则集合来灵活地处理各种业务场景。

核心特性

  • JSON 驱动:规则以 JSON 格式定义,支持动态加载和修改
  • 表达式计算:支持复杂的条件表达式评估
  • 嵌套规则:支持规则之间的嵌套和组合
  • 输入参数映射:灵活地将对象属性映射到规则执行上下文
  • 可扩展性:提供自定义操作符和函数的机制

RulesEngine 如何工作

1. 核心架构

RulesEngine 的执行流程遵循以下设计:

1
输入数据 → 参数映射 → 规则编译 → 条件评估 → 动作执行 → 输出结果

2. 关键组件

RulesEngine 类

这是框架的核心入口,主要职责:

  • 管理规则工作流(Workflow)
  • 执行规则并返回结果
  • 维护规则的生命周期

Workflow 工作流

  • 包含多个 Rule 对象
  • 按顺序执行规则
  • 支持并行处理

Rule 规则

  • 由名称、条件和动作组成
  • 条件(RuleExpressionType)决定是否执行动作
  • 支持嵌套规则(Sub Rules)

RuleExpression 规则表达式

  • 定义规则的执行条件
  • 支持的表达式类型:
    • Lambda:lambda 表达式
    • Inline:内联表达式(关键字+操作符+值)

3. 核心执行机制

参数处理

1
输入对象 → ReflectionUtils → 提取属性值 → 存储到执行上下文

RulesEngine 使用反射机制遍历输入对象的属性,将其转换为规则引擎能理解的参数形式。

表达式评估

  • Lambda 表达式:直接使用 Expression Trees 编译执行
  • Inline 表达式:通过操作符解析器(如 ContainsGreaterThanIn 等)转换为委托执行

动作执行

  • 动作(Action)是规则条件满足时执行的逻辑
  • 支持多个动作的依次执行
  • 动作可以修改输出数据或触发其他规则

4. 规则编译过程

RulesEngine 采用延迟编译策略:

  • 规则首次执行时进行编译
  • 编译结果被缓存以提高后续执行性能
  • 使用 Expression Trees 构建委托,避免每次都解析规则

为什么这样设计

1. 为什么使用 JSON 格式存储规则?

优势

  • 易于持久化:可存储在数据库、配置文件或其他介质
  • 动态加载:无需重新编译代码,运行时修改规则
  • 可读性强:非技术人员也能理解规则逻辑
  • 跨平台兼容:JSON 作为通用格式,便于集成

2. 为什么设计参数映射机制?

规则引擎需要处理各种形式的输入数据(对象、字典、基本类型等),参数映射提供:

  • 统一的数据抽象:屏蔽输入数据的具体形式
  • 灵活的属性访问:支持嵌套属性和集合操作
  • 类型安全性:在编译时进行类型验证

3. 为什么使用表达式树(Expression Trees)?

  • 高性能:编译为机器代码,执行速度接近原生 C# 代码
  • 动态性:在运行时构建和编译表达式
  • 可组合性:支持复杂表达式的组合和优化

4. 为什么要支持嵌套规则?

  • 规则复用:避免重复定义相同的逻辑
  • 模块化设计:提高规则的可维护性和组织性
  • 业务灵活性:应对复杂业务场景需要多层次的决策

5. 为什么采用延迟编译?

  • 启动性能:避免在应用启动时编译所有规则
  • 内存优化:只编译被执行的规则
  • 灵活更新:规则修改后,下次执行时自动重新编译

设计模式与原理

应用的设计模式

  1. Builder 模式:规则的构建使用 FluentAPI,链式调用配置规则属性
  2. Strategy 模式:不同的表达式类型采用不同的计算策略
  3. Factory 模式:操作符工厂创建对应的表达式计算器
  4. Compiler 模式:表达式动态编译为委托

核心原理

反射与元数据

  • 运行时获取对象属性信息
  • 支持嵌套属性访问(如 User.Address.City
  • 处理集合和可空类型

表达式树优化

  • 构建抽象语法树(AST)
  • 编译优化(常量折叠、死代码消除等)
  • 生成高效的委托

缓存策略

  • 规则编译结果缓存
  • 减少重复编译开销
  • 支持缓存失效机制

总结

RulesEngine 通过以下核心设计实现了一个高效、灵活的规则引擎:

  1. 分离关注点:业务规则与业务逻辑解耦
  2. 动态性:支持运行时规则修改和加载
  3. 性能:通过表达式树编译和缓存实现高性能
  4. 可扩展性:提供自定义操作符和规则的机制
  5. 易用性:简洁的 API 和 JSON 配置

这些设计使得 RulesEngine 成为处理复杂业务规则的理想选择,特别是在需要频繁修改业务逻辑的场景中。

本文由作者按照 CC BY 4.0 进行授权