Galosys.Foundation.RulesEngine 26.5.20.1

dotnet add package Galosys.Foundation.RulesEngine --version 26.5.20.1
                    
NuGet\Install-Package Galosys.Foundation.RulesEngine -Version 26.5.20.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Galosys.Foundation.RulesEngine" Version="26.5.20.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Galosys.Foundation.RulesEngine" Version="26.5.20.1" />
                    
Directory.Packages.props
<PackageReference Include="Galosys.Foundation.RulesEngine" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Galosys.Foundation.RulesEngine --version 26.5.20.1
                    
#r "nuget: Galosys.Foundation.RulesEngine, 26.5.20.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Galosys.Foundation.RulesEngine@26.5.20.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Galosys.Foundation.RulesEngine&version=26.5.20.1
                    
Install as a Cake Addin
#tool nuget:?package=Galosys.Foundation.RulesEngine&version=26.5.20.1
                    
Install as a Cake Tool

Galosys.Foundation.RulesEngine

基于 Microsoft RulesEngine 的规则引擎封装,支持 6 种业务场景(折扣/分配/风控/运费/路由/价格),提供统一抽象层、执行模式分发、热更新、降级和可观测能力。

成熟度: 🟡 可用 — 重构中,API 可能变更

快速开始

1. 注入

services.AddRuleEngine(context.Configuration);

2. 配置

// appsettings.json
{
  "Rules": {
    "Path": "rules.json"
  }
}

rules.json 示例:

{
  "discount": [
    {
      "Code": "vip-discount",
      "Name": "VIP会员折扣",
      "Condition": "input.VipLevel >= 2 AND input.OrderAmount >= 500",
      "Output": "new { Type = \"Percentage\", Value = 10m }",
      "Priority": 100,
      "Enabled": true,
      "GroupCode": "MEMBER"
    },
    {
      "Code": "new-user-discount",
      "Name": "新用户首单优惠",
      "Condition": "input.IsNewUser == true AND input.OrderAmount >= 100",
      "Output": "new { Type = \"Fixed\", Value = 20m }",
      "Priority": 90,
      "Enabled": true,
      "GroupCode": "PROMO"
    }
  ]
}

3. 基本用法

var engine = serviceProvider.GetRequiredService<IRuleEngine>();

var result = await engine.ExecuteAsync("discount", new
{
    VipLevel = 2,
    OrderAmount = 800,
    IsNewUser = false
});

if (result.Success)
{
    foreach (var hit in result.Hits.Where(h => h.Matched))
    {
        Console.WriteLine($"命中规则: {hit.Code}, 输出: {hit.Output}");
    }
}

业务场景示例

场景一:折扣/促销(ConflictResolve + GroupExclusive)

互斥组内只取最优折扣,跨组可叠加。

var result = await engine.ExecuteAsync("discount", cart, new RuleExecuteOption
{
    Mode = RuleExecuteMode.ConflictResolve,
    ConflictStrategy = ConflictStrategy.GroupExclusive
});

foreach (var group in result.Hits.Where(h => h.Matched).GroupBy(h => h.GroupCode))
{
    Console.WriteLine($"组 {group.Key}: {group.First().Code} -> {group.First().Output}");
}

场景二:库存分配(FirstMatch + FallbackChain)

SKU 级参数 > 店铺级 > 全局级,参数回退链合并后用于分配规则。

var merged = FallbackChain.Merge<AllocationParams>(skuLevel, storeLevel, global);

var result = await engine.ExecuteAsync("allocation", new
{
    SkuId = "SKU001",
    RequestQty = 100,
    AvailableStock = merged.MaxAllocate,
    AllocatePct = merged.AllocatePct,
    SafetyStock = merged.SafetyStock
}, new RuleExecuteOption
{
    Mode = RuleExecuteMode.FirstMatch
});

if (result.Hits.FirstOrDefault(h => h.Matched) is { } hit)
{
    Console.WriteLine($"分配策略: {hit.Code} -> {hit.Output}");
}

场景三:风控/欺诈检测(AllEvaluate + RiskScore)

全部规则执行,累加风控分数,超阈值触发告警。

var result = await engine.ExecuteAsync("risk", new
{
    UserId = "U10086",
    OrderAmount = 5000m,
    IpAddress = "192.168.1.1",
    DeviceFingerprint = "abc123",
    OrderCount24h = 8
}, new RuleExecuteOption
{
    ScoreThreshold = 80
});

Console.WriteLine($"风控总分: {result.TotalScore}, 是否拦截: {result.TotalScore >= 80}");

场景四:运费计算(AllEvaluate 附加费叠加)

多条附加费规则叠加计算总运费。

var result = await engine.ExecuteAsync("shipping", new
{
    Region = "偏远地区",
    Weight = 15.5m,
    IsOversized = true,
    IsFragile = true
});

decimal totalShipping = baseShippingFee;
foreach (var hit in result.Hits.Where(h => h.Matched))
{
    var surcharge = JsonSerializer.Deserialize<SurchargeOutput>(hit.Output!);
    totalShipping += surcharge.Amount;
}

场景五:订单路由(FirstMatch 三次调用)

分三次调用:仓库匹配 → 物流商匹配 → 特殊处理匹配。

var orderCtx = new { OrderId = "ORD001", Region = "华东", SkuCategory = "生鲜" };

var warehouse = await engine.ExecuteAsync("route-warehouse", orderCtx, new RuleExecuteOption
{
    Mode = RuleExecuteMode.FirstMatch
});

var carrier = await engine.ExecuteAsync("route-carrier", orderCtx, new RuleExecuteOption
{
    Mode = RuleExecuteMode.FirstMatch
});

var special = await engine.ExecuteAsync("route-special", orderCtx, new RuleExecuteOption
{
    Mode = RuleExecuteMode.FirstMatch
});

场景六:价格引擎(FirstMatch 价格瀑布)

客户协议价 > 会员价 > 促销价 > 基准价,按优先级瀑布式匹配。

var result = await engine.ExecuteAsync("pricing", new
{
    CustomerId = "C001",
    SkuId = "SKU001",
    CategoryCode = "ELECTRONICS",
    IsVip = true,
    IsPromoActive = true
}, new RuleExecuteOption
{
    Mode = RuleExecuteMode.FirstMatch
});

if (result.Hits.FirstOrDefault(h => h.Matched) is { } priceHit)
{
    var price = JsonSerializer.Deserialize<PriceOutput>(priceHit.Output!);
    Console.WriteLine($"命中最优价格: {priceHit.Code}, 价格: {price.Amount}");
}

Fluent API 定义规则

var rule = RuleBuilder.Create()
    .Code("vip-discount")
    .Name("VIP会员折扣")
    .RuleSet("discount")
    .When("input.VipLevel >= 2 AND input.OrderAmount >= 500")
    .Then("new { Type = \"Percentage\", Value = 10m }")
    .Priority(100)
    .Group("MEMBER")
    .Tag("会员", "折扣")
    .Build();

参数回退链(FallbackChain)

多层参数合并,高优先级覆盖低优先级的非 NULL 值。

var skuLevel = new AllocationParams { MaxAllocate = 200 };
var storeLevel = new AllocationParams { AllocatePct = 80, SafetyStock = 50 };
var global = new AllocationParams
{
    StrategyType = "FIFO",
    MaxAllocate = 0,
    MinAllocate = 1,
    AllocatePct = 100
};

var merged = FallbackChain.Merge<AllocationParams>(skuLevel, storeLevel, global);
// MaxAllocate=200(SKU), AllocatePct=80(店铺), SafetyStock=50(店铺),
// StrategyType=FIFO(全局), MinAllocate=1(全局)

热更新

{
  "Rules": {
    "Path": "rules.json",
    "HotReload": true,
    "HotReloadMode": "FileWatcher"
  }
}
模式 说明 适用场景
FileWatcher 监听配置文件变更(默认) 单实例 / 开发环境
Redis Redis Pub/Sub 多实例同步 多实例部署(需 Redis 模块)
Polling 定时轮询版本比对 数据库规则源

降级

规则引擎不可用时自动降级,返回默认结果而不阻塞业务。

{
  "Rules": {
    "FallbackEnabled": true
  }
}

降级时 RuleExecuteResult.Success = falseHits 为空,Error 包含降级原因。

可观测性

事件监听

实现 IRuleEventListener 并标注 [Service] 自动注册:

[Service]
public class AuditRuleListener : IRuleEventListener
{
    public Task OnBeforeEvaluateAsync(string ruleSet, object input) => Task.CompletedTask;

    public Task OnRuleMatchedAsync(string ruleSet, RuleHit hit) => Task.CompletedTask;

    public Task OnRuleFailedAsync(string ruleSet, RuleHit hit, Exception ex) => Task.CompletedTask;

    public Task OnAfterEvaluateAsync(string ruleSet, RuleExecuteResult result) => Task.CompletedTask;
}

OpenTelemetry Metrics

指标 类型 标签
galosys.rules.execution.total Counter rule_set
galosys.rules.execution.duration Histogram rule_set
galosys.rules.match.total Counter rule_set, rule_code
galosys.rules.error.total Counter rule_set, error_type

配置参考

{
  "Rules": {
    "Path": "rules.json",
    "HotReload": true,
    "HotReloadMode": "FileWatcher",
    "HotReloadInterval": "00:00:05",
    "FallbackEnabled": true,
    "MetricsEnabled": true
  }
}

相关模块

模块 说明 NuGet
Galosys.Foundation.RulesEngine 核心模块(本模块) 必选
Galosys.Foundation.RulesEngine.EntityFrameworkCore 数据库规则存储 可选
Galosys.Foundation.RulesEngine.Redis Redis Pub/Sub 热更新广播 可选

命名空间

所有抽象接口和模型位于 Microsoft.Extensions.Rules,调用方无需额外 using。

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Galosys.Foundation.RulesEngine:

Package Downloads
Galosys.Foundation.RulesEngine.Redis

Galosys.Foundation快速开发库

Galosys.Foundation.RulesEngine.EntityFrameworkCore

Galosys.Foundation快速开发库

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
26.5.20.1 121 5/20/2026
26.5.19.1 136 5/19/2026
26.5.18.1 135 5/18/2026
26.5.15.1 142 5/15/2026
26.5.12.3 125 5/12/2026
26.5.12.2 130 5/12/2026
26.4.27.1-rc1 94 4/26/2026
26.4.25.1-rc1 91 4/25/2026
26.4.22.2-rc7 97 4/22/2026
26.4.22.2-rc6 75 4/22/2026
26.4.22.2-rc4 93 4/22/2026
26.4.22.2-rc3 85 4/22/2026
26.4.19.1-rc1 92 4/19/2026
26.4.12.8-rc1 96 4/12/2026
26.4.12.7-rc1 98 4/12/2026
26.4.12.5-rc1 96 4/12/2026
26.1.30.1-rc1 110 1/30/2026
26.1.29.1 119 1/29/2026
26.1.28.5 114 1/28/2026
26.1.28.4 113 1/28/2026
Loading failed