C# RulesEngine 規則引擎:從入門到看懵

說明RulesEngine 是 C# 寫的一個規則引擎類庫,讀者可以從這些地方了解它:
倉庫地址:
https://github.com/microsoft/RulesEngine
使用方法:
https://microsoft.github.io/RulesEngine
文檔地址:
https://github.com/microsoft/RulesEngine/wiki
什么是規則引擎?

照搬 https://github.com/microsoft/RulesEngine/wiki/Introduction#what-is-the-rules-engine
在企業項目中,關鍵或核心部分總是業務邏輯或業務規則 , 也就是 CRUD , 這些系統都有一個共同的特征是,某個模塊中的一些或許多規則或策略總會發生變化,例如購物網站的顧客折扣、物流企業的運價計算等 。隨著這些變化而來的是大量的重復工作,如果系統沒有足夠的抽象,那么每當增加一種規則時 , 開發者需要在規則、回歸測試、性能測試等方面的變化中編寫代碼 。
在 RulesEngine 中,微軟對規則進行了抽象,這樣核心邏輯總是得到穩定的、易于維護的,而規則的更改可以以一種簡單的方式生成,而不需要更改代碼庫 。此外,系統的輸入本質上是動態的,因此不需要在系統中定義模型,而是可以作為擴展對象或任何其他類型的對象作為輸入,系統經過預定義的規則處理后,輸出結果 。
它有以下特性:
  • Json based rules definition(基于 Json 的規則定義)
  • Multiple input support(多輸入支持)
  • Dynamic object input support(動態對象輸入支持)
  • C# Expression support(C # 表達式支持)
  • Extending expression via custom class/type injection(通過自定義類/類型注入擴展表達式)
  • Scoped parameters(范圍參數)
  • Post rule execution actions(發布規則執行操作)

C# RulesEngine 規則引擎:從入門到看懵

文章插圖
說人話就是,業務邏輯的輸出結果受到多個因子影響 , 但是這些影響有一定規律的,那么適合將這些部分抽象出來 , 接著使用規則引擎處理 , 例如購物的各種優惠卷疊加之后的最終折扣價、跨區運輸的不同類型的包裹運價計算等 。
筆者認為這個規則引擎主要由兩部分構成:
  • 規則驗證系統,例如根據規則驗證字段、執行函數驗證當前流程、輸出執行結果;
  • 動態代碼引擎,能夠將字符串轉換為動態代碼,利用表達式樹這些完成;
當然,這樣說起來其實很抽象的,還得多擼代碼 , 才能明白這個 RulesEngine 到底是干嘛的 。
安裝新建項目后,nuget 直接搜索 RulesEngine 即可安裝 , 在 nuget 介紹中可以看到 RulesEngine 的依賴:
C# RulesEngine 規則引擎:從入門到看懵

文章插圖
【C# RulesEngine 規則引擎:從入門到看懵】FluentValidation 是一個用于構建強類型驗證規則的 .NET 庫,在 ASP.NET Core 項目中,我們會經常使用模型驗證 , 例如必填字段使用 [Required]、字符串長度使用 [MaxLength] 等;但是因為是特性注解,也就是難以做到很多需要經過動態檢查的驗證方式,使用 FluentValidation 可以為模型類構建更加豐富的驗證規則 。
而 FluentValidation 用在 RulesEngine 上,也是相同的用途,RulesEngine 最常常用做規則驗證,檢查模型類或業務邏輯的驗證結果 , 利用 FluentValidation中豐富的驗證規則,可以制作各種方便的表達式樹,構建動態代碼 。
怎么使用我們通過 RulesEngine 檢查模型類的字段是否符合規則,來了解 RulesEngine 的使用方法 。
創建一個這樣的模型類:
public class Buyer{public int Id { get; set; }public int Age { get; set; }// 是否為已認證用戶public bool Authenticated { get; set; }}場景是這樣的 , 用戶下單購買商品,后臺需要判斷此用戶是否已經成年、是否通過了認證 。
正常來看代碼應該這樣寫:
if(Authenticated == true && Age > 18)但是如果年齡調為 16 歲呢?如果最近公司搞活動,不需要上傳身份證就能購買商品呢?
當然定義變量存儲到數據庫也行,但是如果后面又新增了幾個條件,那么我們就需要修改代碼了,大佬說,這樣不好,我們要 RulesEngine。
好的 , 那我們來研究一下這個東西 。
前面提到的 if(Authenticated == true && Age > 18),這么一個完整的驗證過程,在 RulesEngine 稱為 Workflow,每個 Workflow 下有多個 Rule 。
if(Authenticated == true && Age > 18) => WorkflowAuthenticated == true=> RuleAge > 18=> Rule

推薦閱讀