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 的域組件與插件編程.