Natasha 5.0 版本已于 2022/10/10 日發(fā)布, 此次大版本更迭帶來了兼容性支持, 目前 Natasha 可以兼容 standard2.0 及 coreapp3.1 以上版本.
創(chuàng)新互聯(lián)是一家專業(yè)提供吉林企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、HTML5、小程序制作等業(yè)務(wù)。10年已為吉林眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。
下載使用
NuGet\Install-Package DotNetCore.Natasha.CSharp -Version 5.0.0
.
該版本分離了編譯引擎, Natasha 將根據(jù)
目標(biāo)版本來適配對(duì)外的 API.
單域編譯引擎
兼容 Standard2.0(Core3.1 以下) 版本, 動(dòng)態(tài)構(gòu)建將在主域中進(jìn)行, 您無法體驗(yàn)到多域編程帶來的好處, 也無法卸載動(dòng)態(tài)編譯輸出的程序集.
不兼容舊版 Natasha API, 舊版 Natasha 僅支持多域編程, 并提供了多域方面的 API, 而單域引擎是從多域引擎分離簡化而來, 它將失去一些非必要的 API.
多域編譯引擎
兼容 Core3.1 以上版本, 支持程序集卸載, 域功能隔離, 插件加載卸載等操作.
兼容舊版 Natasha API, 本次升級(jí)保留了多域環(huán)境應(yīng)有的 API, 未做改變, .
本次版本在源碼層,分為 MultiDomain / Public / SingleDomain 三部分, 并使用自定義宏 MULTI
來區(qū)分單/多域, 從工程文件上做兼容隔離允許 Natasha 后續(xù)的升級(jí)工作不必過多的關(guān)注兼容性代碼, 多域引擎仍然是 Natasha 未來版本的主戰(zhàn)場(chǎng), 迭代優(yōu)化工作將在 MultiDomain 文件夾中進(jìn)行.
相比較有特色的 API {OperatorClass}.DefaultDomain/CreateDomain/RandomDomain/UseDomain
單域版僅有 {OperatorClass}.DefaultDomain
一個(gè) API, 單域引擎的編譯結(jié)果均加載到主域中, 因此也不具備隔離和卸載功能.
編譯前提 : 使用 字符串腳本 需要對(duì)編譯原理有一定的了解, Roslyn 及 Natasha 簡化了復(fù)雜的理論依據(jù)及構(gòu)建過程, 使用 Natasha 您只需關(guān)注3點(diǎn):
元數(shù)據(jù)管理, 熟悉 Emit / Expression 的同學(xué)應(yīng)該清楚, 在構(gòu)建過程中可能用到反射, 比如 propertyInfo / fieldInfo / methodInfo, 因?yàn)樵诰幊讨兄魂P(guān)注使用,而忽視了元數(shù)據(jù)對(duì)動(dòng)態(tài)編譯的重要性, 從而切換到字符串編譯的時(shí)候出現(xiàn)各種各樣的問題, Roslyn 和 Natasha 同樣是需要元數(shù)據(jù)的, 而元數(shù)據(jù)的來源有 引用程序集,內(nèi)存程序集,實(shí)際程序集, 除內(nèi)存程序集外元數(shù)據(jù)均記錄在 DLL 文件中, 因此您可以看到一些構(gòu)建代碼是這樣: NatashaManagement.AddGlobalReference("1.dll");
這一步的缺失可能導(dǎo)致錯(cuò)誤: 找不到 RuntimeMetadataVersion 的值。找不到包含 System.Object 的程序集,或未通過選項(xiàng)為 RuntimeMetadataVersion 指定值。
, 引用管理對(duì)程序來講是有一定負(fù)擔(dān)的, 因?yàn)槟壳斑€不能從內(nèi)存程序集中提取元數(shù)據(jù), 所以需要以文件方式來添加, 這也導(dǎo)致你發(fā)布動(dòng)態(tài)編譯的程序時(shí)需要有完備的引用文件跟隨, 因此會(huì)導(dǎo)致您發(fā)布的包體積變大, 至于環(huán)境需要哪些引用文件我們交給 DotNetCore.Compile.Environment
環(huán)境包來解決, 如果您不能很好的管理引用, 請(qǐng)引入該包全面覆蓋當(dāng)前程序的元數(shù)據(jù).
Using 管理, 這關(guān)乎著元數(shù)據(jù)的引用來源, 任何動(dòng)態(tài)構(gòu)建都是以一個(gè)完整類方式進(jìn)行, 那么完整的類 using 代碼是必不可少的一部分, Natasha 的構(gòu)建模板可以覆蓋大部分 using 并有語義過濾處理異常 using, 如果您直接使用 AssemblyCSharpBuilder
來構(gòu)建代碼則需要注意腳本中的 using 部分.
編譯環(huán)境 : 編譯環(huán)境包已不在新版的 Natasha 中,推薦使用 Natasha 的 API NatashaManagement.AddGlobalReference/AddGlobalUsing
來管理全局引用及 Using 緩存, 如果您不能很好管理的元數(shù)據(jù)引用, 請(qǐng)引入 DotNetCore.Compile.Environment
包來解決元數(shù)據(jù)引用的問題.
輸出環(huán)境 : 若您覺得生成文件中有較多的多語言適配, 可以使用
來指定默認(rèn)的資源語言.
二義性錯(cuò)誤 : 該問題仍然被歸屬到用戶的錯(cuò)誤編程行為中, 并不該由 IDE 或 Natasha 自動(dòng)解決, 我仍傾向于在命名空間發(fā)生沖突時(shí)由用戶手動(dòng)改解決該問題, 上下文語義環(huán)境不能百分百推測(cè)出用戶想使用某個(gè)命名空間.目前推薦的三種方法:
Natasha.CSharp.Extension.Ambiguity
擴(kuò)展包及 .Using()/.ConfigUsing()
模板自帶的方法指定優(yōu)先級(jí)最高的 Using. (該包將在不久后以獨(dú)立項(xiàng)目存在,它并不屬于 Natasha 項(xiàng)目, 晚于 Natasha5.0 發(fā)布)AssemblyCSharpBuilder
編譯字符串, 在字符串層面替換.assemblyCSharpBuilder.AddSemanticAnalysistor(Func)
(需要有語法語義相關(guān)編程經(jīng)驗(yàn)).一個(gè)盡可能復(fù)雜的案例:
var action = NDelegate
//使用隨機(jī)域 也可以使用 CreateDomain / UseDomain / DefaultDomain
//Core3.1以下僅能使用 DefaultDomain
.DefaultDomain()
//[可選API] 必要時(shí)使用 ConfigBuilder 配置編譯單元(下面只為展示API, 有需求就用, 沒需求不用寫)
.ConfigBuilder(builder => builder
//配置編譯器選項(xiàng)
.ConfigCompilerOption(opt => opt
//配置平臺(tái)
.SetPlatform(Microsoft.CodeAnalysis.Platform.AnyCpu)
//Release 方式編譯
.CompileAsRelease()
//開啟可空警告
.SetNullableCompile(Microsoft.CodeAnalysis.NullableContextOptions.Warnings))
//配置語法選項(xiàng)
.ConfigSyntaxOptions(opt => opt
//配置支持的腳本語言版本
.WithLanguageVersion(Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8))
//禁用語義檢查與過濾
.DisableSemanticCheck()
)
//[可選API] 配置該方法所在的類模板
.ConfigClass(item => item
//給類配置一個(gè)名字,不用隨即名
.Name("myClass")
//不使用默認(rèn)域的 Using 緩存
.NoGlobalUsing())
//[可選API] 為類模板添加 using 引用
.ConfigUsing("System")
//這里的 API 參照定義的委托, 包括委托的參數(shù)
//例如 Action / Func 擁有一個(gè)參數(shù), 參數(shù)的名字請(qǐng)?jiān)?Action / Func 上 F12 查看定義獲取參數(shù)名.
.Action("Console.WriteLine(\"Hello World!\");");
action(); /*Output: Hello World!*/
更多案例 更多文檔
IndexOf
替代 Contans
方法做兼容.DotNetCore.SourceLink.Environment
依賴以支持 netstandard2.0/1 版本.DotNetCore.Compile.Environment
依賴以支持 netstandard2.0/1 版本.