Natasha 簡介
- Natasha 是一個基於 Roslyn 的動態編譯類庫, 它以極簡的 API 完成了動態編譯的大部分功能, 使用它可以在程式執行時編譯出新的程式集.
- Natasha 允許開發人員直接使用 C# 程式碼即可編寫執行時的功能, 避免了 Emit 的學習,開發,維護的成本.
- Natasha 的編譯單元的基本輸出是程式集, 程式集載入在域中, 使用該類庫可以建立域,並在不同的域內建立新的功能, 也支援可以解除安裝域.
- Natasha 為開發人員提供了外掛管理的功能, 並內建解析依賴的功能, 我們可以有針對性的載入和解除安裝外掛及其依賴.
- 使用 Natasha 我們可以快速的實現 mapper/類庫粘合/業務邏輯組裝/動態代理/協議轉換等等, 使用 Natasha 需要一定的程式設計基礎,有動態編譯經驗相關的實踐.儘管 Natasha 可以輸出詳細日誌,但是動態功能的開發本應該是邏輯暢通,程式碼規範的,如果你不能保證程式碼是暢通的,且沒有動態編譯的思維可以先找相關的文章進行學習.
Natasha 進化
Natasha 自 v3.0.0 版本之後,進行了比較大的革新,以下我列舉一些比較重要的:
-
移除對 standard2.0 / core2.1-3.0 的支援, 目前支援的版本為: net3.1/5.0/6.0, 相容版本已歸檔至其他分支.
Runtime 是 Natasha 的強依賴, .NET 從 3.0 起, Runtime 升級了很多新的特性, 比如支援可空引用及後設資料處理, 支援 ALC 高階特性, 方便的外掛依賴解析方案等等, 另外由於個人精力有限, 最終決定從分水嶺 3.1 開始做相容. -
語義過濾, 自 v3.0.0 以後, Natasha 新增了語義層, 這讓 Natasha 顯得更加智慧, 我們可以根據自己的需求去解析和重組語法語義.
比如 Natasha 內建的語義處理, 其中有一個功能是將無用的 using 移除掉, 只保留有用的 using. 大大減少了日誌輸出的程式碼, 讓開發者一眼看到有用的程式碼邏輯.
編譯一段程式碼, 需要引用後設資料,需要準備 using,需要寫正確的程式碼,最後是輸出方式, 為了讓開發者以最快速度上手, Natasha 解決了後設資料引用問題,以及 using 覆蓋問題, 另對外提供了輸出 API, 理論上開發者需要關注的是自己如何編寫一段動態程式碼, 如何與執行時其他功能接洽配合.另針對名稱空間濫用導致的多義性引用問題, 我們提供了語義擴充套件包
Natasha.CSharp.Extension.Ambiguity
-
效能優化, 優化是 Natasha 一直在做的事情, Natasha 在預熱方法上進行了一些併發的改造, 以便讓相互無關的任務並行初始化, 除此之外也移除了 AdWorkspace 程式碼, 這些帶碼均由高效能的方案取代. 針對效能敏感場景, 我們增加了預熱時全域性修剪錯誤語義,以及禁用語義過濾的 API, 以便讓編譯更快的發生.
-
新特性支援. 支援 c# 最高語言版本, 支援可空引用的編譯(預設關閉), dll/pdb/xml 檔案手動選擇生成. Natasha 4.0 的原始碼使用了可空引用支援, 因此支援可空引用專案的接入和使用, 在方法呼叫的上下游明確了可空界限. 但在動態編譯層面,嘗試可空引用的後設資料解析功能時,我遇到了無法解決的難題, 可空引用的頂層泛型傳遞是無法正確解析的, 因此在 Action<string?> 等後設資料解析中,無法得到正確結果, 另外方法返回值可空引用解析也未找到方法, 綜上 Natasha 預設關閉了動態編譯初始化中的可空引用的選項, 開發者需要自行開啟.
-
重構引用管理, 4.0 重構了 Natasha 的引用管理, 經過探索我們最終選定以 AssemblyName 作為引用版本管理的依據, 並在預熱過程中採用只讀上下文解析引用.
-
重構外掛管理, 4.0 重構了 Natasha.Domain 域實現, 摘除了對引用管理的耦合, 讓 NatashaDomain 更專注於程式集及其依賴的載入與解除安裝, 此次對外提供了4個方法以便於使用者在載入外掛時管理不同版本的依賴.
-
重構日誌模組, 4.0 版本後日志將由使用者自行控制寫入和獲取, 對外提供編譯後的日誌處理事件, Natasha 將不再負責日誌的 IO 部分.
-
重構異常模組, 4.0 重構了 Natasha 的編譯單元, 其中語法轉換階段如果出錯會丟擲異常, 之後編譯不成功也會丟擲異常, 並提供編譯成功和失敗事件.
Natasha 實戰應用
Natasha 已經在網友公司及我司得到了廣泛應用, 比如:客戶端指令碼定製, 動態計分系統, 低程式碼應用中的邏輯組裝與編譯, 類庫中字串到表示式樹的轉換, 基於演算法的高效能只讀併發字典, 忽略類庫版本的程式碼粘合劑, 實體對映, 動態路由, 動態RPC, 動態定時任務等等.
Natasha 與其他技術
-
SG(Source Generetor)
首先來講 Natasha 與 SG 有重疊的部分, 但也有各自取代不了的地方. 我認為比較好的組合是, SG 提供靜態約束, Natasha 來提供動態實現.
-
AOT
Natasha 是儘可能覆蓋全面的程式集和引用, 剪裁需謹慎, 另外 AOT 不會取代動態編譯, 只會平行發展.
Natasha 未來規劃
Natasha 完成了自己的核心任務,但它還有很長一段的路要走, 期待大家的反饋.
後續 Natasha 還有一些方案需要調研, 一些應用需要開發, 例如:域的強制解除安裝方案, 基於 Asp.net 的動態開發框架, 高度靈活的高效能實體對映庫等.
下一篇將介紹 Natasha 的域元件與外掛程式設計.