Natasha 5.0 版本已于 2022/10/10 日发布, 此次大版本更迭带来了兼容性支持, 目前 Natasha 可以兼容 standard2.0 及 coreapp3.1 以上版本.

下载使用 NuGet\Install-Package DotNetCore.Natasha.CSharp -Version 5.0.0.

引擎分离

该版本分离了编译引擎, Natasha 将根据 <TargetFramework> {NET VERSION} </TargetFramework> 目标版本来适配对外的 API.

  • 单域编译引擎

    • 兼容 Standard2.0(Core3.1 以下) 版本, 动态构建将在主域中进行, 您无法体验到多域编程带来的好处, 也无法卸载动态编译输出的程序集.

    • 不兼容旧版 Natasha API, 旧版 Natasha 仅支持多域编程, 并提供了多域方面的 API, 而单域引擎是从多域引擎分离简化而来, 它将失去一些非必要的 API.

  • 多域编译引擎

    • 兼容 Core3.1 以上版本, 支持程序集卸载, 域功能隔离, 插件加载卸载等操作.

    • 兼容旧版 Natasha API, 本次升级保留了多域环境应有的 API, 未做改变, .

代码分离

本次版本在源码层,分为 MultiDomain / Public / SingleDomain 三部分, 并使用自定义宏 MULTI 来区分单/多域, 从工程文件上做兼容隔离允许 Natasha 后续的升级工作不必过多的关注兼容性代码, 多域引擎仍然是 Natasha 未来版本的主战场, 迭代优化工作将在 MultiDomain 文件夹中进行.

相比较有特色的 API {OperatorClass}.DefaultDomain/CreateDomain/RandomDomain/UseDomain 单域版仅有 {OperatorClass}.DefaultDomain 一个 API, 单域引擎的编译结果均加载到主域中, 因此也不具备隔离和卸载功能.

使用须知

  • 编译前提 : 使用 字符串脚本 需要对编译原理有一定的了解, Roslyn 及 Natasha 简化了复杂的理论依据及构建过程, 使用 Natasha 您只需关注3点:

    • 元数据管理, 熟悉 Emit / Expression 的同学应该清楚, 在构建过程中可能用到反射, 比如 propertyInfo / fieldInfo / methodInfo, 因为在编程中只关注使用,而忽视了元数据对动态编译的重要性, 从而切换到字符串编译的时候出现各种各样的问题, Roslyn 和 Natasha 同样是需要元数据的, 而元数据的来源有 引用程序集,内存程序集,实际程序集, 除内存程序集外元数据均记录在 DLL 文件中, 因此您可以看到一些构建代码是这样: NatashaManagement.AddGlobalReference("1.dll"); 这一步的缺失可能导致错误: 找不到 RuntimeMetadataVersion 的值。找不到包含 System.Object 的程序集,或未通过选项为 RuntimeMetadataVersion 指定值。, 引用管理对程序来讲是有一定负担的, 因为目前还不能从内存程序集中提取元数据, 所以需要以文件方式来添加, 这也导致你发布动态编译的程序时需要有完备的引用文件跟随, 因此会导致您发布的包体积变大, 至于环境需要哪些引用文件我们交给 DotNetCore.Compile.Environment 环境包来解决, 如果您不能很好的管理引用, 请引入该包全面覆盖当前程序的元数据.

    • Using 管理, 这关乎着元数据的引用来源, 任何动态构建都是以一个完整类方式进行, 那么完整的类 using 代码是必不可少的一部分, Natasha 的构建模板可以覆盖大部分 using 并有语义过滤处理异常 using, 如果您直接使用 AssemblyCSharpBuilder 来构建代码则需要注意脚本中的 using 部分.

  • 编译环境 : 编译环境包已不在新版的 Natasha 中,推荐使用 Natasha 的 API NatashaManagement.AddGlobalReference/AddGlobalUsing 来管理全局引用及 Using 缓存, 如果您不能很好管理的元数据引用, 请引入 DotNetCore.Compile.Environment 包来解决元数据引用的问题.

  • 输出环境 : 若您觉得生成文件中有较多的多语言适配, 可以使用 <SatelliteResourceLanguages>en</SatelliteResourceLanguages> 来指定默认的资源语言.

  • 二义性错误 : 该问题仍然被归属到用户的错误编程行为中, 并不该由 IDE 或 Natasha 自动解决, 我仍倾向于在命名空间发生冲突时由用户手动改解决该问题, 上下文语义环境不能百分百推测出用户想使用某个命名空间.目前推荐的三种方法:

    • 使用 Natasha.CSharp.Extension.Ambiguity 扩展包及 .Using()/.ConfigUsing() 模板自带的方法指定优先级最高的 Using. (该包将在不久后以独立项目存在,它并不属于 Natasha 项目, 晚于 Natasha5.0 发布)
    • 直接使用引擎 AssemblyCSharpBuilder 编译字符串, 在字符串层面替换.
    • 自写语义过滤方法, 更新编译单元中的语法树, 使用 Natasha 的语义扩展方法来添加您的过滤方法assemblyCSharpBuilder.AddSemanticAnalysistor(Func<AssemblyCSharpBuilder, CSharpCompilation, CSharpCompilation>) (需要有语法语义相关编程经验).

案例

一个尽可能复杂的案例:

var action = NDelegate

//使用随机域 也可以使用 CreateDomain / UseDomain / DefaultDomain
//Core3.1以下仅能使用 DefaultDomain
.DefaultDomain() //[可选API] 必要时使用 ConfigBuilder 配置编译单元(下面只为展示API, 有需求就用, 没需求不用写)
.ConfigBuilder(builder => builder //配置编译器选项
.ConfigCompilerOption(opt => opt
//配置平台
.SetPlatform(Microsoft.CodeAnalysis.Platform.AnyCpu)
//Release 方式编译
.CompileAsRelease()
//开启可空警告
.SetNullableCompile(Microsoft.CodeAnalysis.NullableContextOptions.Warnings)) //配置语法选项
.ConfigSyntaxOptions(opt => opt
//配置支持的脚本语言版本
.WithLanguageVersion(Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8)) //禁用语义检查与过滤
.DisableSemanticCheck()
) //[可选API] 配置该方法所在的类模板
.ConfigClass(item => item
//给类配置一个名字,不用随即名
.Name("myClass")
//不使用默认域的 Using 缓存
.NoGlobalUsing()) //[可选API] 为类模板添加 using 引用
.ConfigUsing("System") //这里的 API 参照定义的委托, 包括委托的参数
//例如 Action<int> / Func<int,int> 拥有一个参数, 参数的名字请在 Action<int> / Func<int,int> 上 F12 查看定义获取参数名.
.Action("Console.WriteLine(\"Hello World!\");"); action(); /*Output: Hello World!*/

更多案例 更多文档

更新日志

  • 2022/09/05 - 2022/09/21

    • 分离引擎, 项目分为多域和单域, 以部分类方式合并 API.
    • 使用 IndexOf 替代 Contans 方法做兼容.
    • 支持 netstandard2.0 及 coreapp3.1,net5.0,net6.0 版本.
    • 升级 DotNetCore.SourceLink.Environment 依赖以支持 netstandard2.0/1 版本.
    • 升级 DotNetCore.Compile.Environment 依赖以支持 netstandard2.0/1 版本.
  • 2022/09/30 - 2022/10/09

    • 使用 Assembly.ReflectionOnlyLoad 替代 MetadataLoadContext 解决单域引擎只读元数据的问题.
    • 优化单域引擎初始化过程中扫描源dll文件的问题.

动态编译库 Natasha 5.0 兼容版本发布的更多相关文章

  1. 基于roslyn的动态编译库Natasha

    人老了,玩不转博客园的编辑器,详细信息转到:https://mp.weixin.qq.com/s/1r6YKBkyovQSMUgfm_VxBg 关键字:Github, NCC, Natasha,Ros ...

  2. QuantumTunnel:v1.0.0 正式版本发布

    经过一段时间运行,代码已经稳定是时候发布正式版本了! v1.0.0 正式版本发布 对核心能力的简要说明: 支持协议路由和端口路由:QuantumTunnel:端口路由 vs 协议路由 基于Netty实 ...

  3. 动态线程池框架 DynamicTp v1.0.6版本发布。还在为Dubbo线程池耗尽烦恼吗?还在为Mq消费积压烦恼吗?

    DynamicTp 简介 DynamicTp 是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为 动态调参.通知报警.运行监控.三方包线程池管理等几大类. 经过几个版本迭代,目前最新 ...

  4. 面向UI编程:ui.js 1.0 粗糙版本发布,分布式开发+容器化+组件化+配置化框架,从无到有的艰难创造

    时隔第一次被UI思路激励,到现在1.0的粗糙版本发布,掐指一算整整半年了.半年之间,有些细节不断推翻重做,再推翻再重做.时隔今日,终于能先出来个东西了,这个版本很粗糙,主体功能大概能实现了,但是还是有 ...

  5. Apache Dolphinscheduler3.0.0-beta-1 版本发布,新增FlinkSQL、Zeppelin任务类型

    导读:近日,Apache Dolphin Scheduler 迎来了 3.0.0-beta-1 版本的正式发布.新版本主要针对 3.0.0-alpha 进行了代码和文档的修复,并引入了部分的功能,如支 ...

  6. LogDashboard 1.0.4 版本发布

    LogDashboard 1.0.4 版本 有关LogDashboard的介绍请看这里.logDashboard已经发布了1.0.4版本 有关这个版本的详细变化可以在Github上的里程碑上查看 支持 ...

  7. ML.NET 0.9 版本发布---.net下的机器学习引擎

    欢迎来到 2019年!在过去的9个月里, 我们一直在为ML.NET添加新的特征和改进相关功能.在提交1.0版本之前,我们将专注于包的整体稳定性并对API进行不断优化, 扩大测试的覆盖面并对开发文档进行 ...

  8. NHibernate 1.0 Released 版本发布了

    NHibernate is a port of Hibernate to the .NET platform. Hibernate is the leading open-source object- ...

  9. ScutSDK 0.9版本发布

    ScutSDK简介: ScutSDK是和Scut游戏服务器引擎,简化客户端开发的配套SDK,她彻底打通了Scut开源游戏服务器引擎与客户端引擎(如Cocos2d-x/Quick-x/Unity3D)项 ...

随机推荐

  1. php和js的不定参

    function my_func() { $args = func_get_args(); print_r($args); } my_func('php','java','node.js'); jav ...

  2. SAM复杂度证明

    关于$SAM$的复杂度证明(大部分是对博客的我自己的理解和看法) 这部分是我的回忆,可省略 先回忆一下$SAM$ 我所理解的$SAM$,首先扒一张图 初始串$aabbabd$ 首先发现,下图里的$S- ...

  3. ASP.NET Core 6框架揭秘实例演示[32]:错误页面的集中呈现方式

    由于ASP.NET是一个同时处理多个请求的Web应用框架,所以在处理某个请求过程中出现异常并不会导致整个应用的中止.出于安全方面的考量,为了避免敏感信息外泄,客户端在默认情况下并不会得到详细的出错信息 ...

  4. 如何开发一款基于 Vite+Vue3 的在线表格系统(上)

    今天,葡萄带你了解如何基于Vite+Vue3实现一套纯前端在线表格系统. 在正式开始项目介绍之前,首先咱们首先来介绍一下Vite和Vue3. Vue3 Vue是什么?大多前端开发者对这个词已毫不陌生了 ...

  5. java学习第二天面向对象.day07

    变量的生命周期 成员变量:存储在堆内存中,随着对象的销毁而销毁 局部变量:存储在栈内存中,随着所定义方法的调用结束而销毁 局部变量存储在方法中,每次调用方法都会在栈空间开辟一块内存空间--栈帧,方法调 ...

  6. Linux—权限管理

    Linux 权限管理 1.权限简介 Linux权限是操作系统用来限制对资源访问的机制,权限一般分为读.写.执行.系统中每个文件都拥有特定的权限:属主.属组以及其他人,通过这样的机制来限制哪些用户或用户 ...

  7. Express 设置请求跨域

    import cors from "cors"; import express from "express"; const app = express(); a ...

  8. 我就获取个时间,机器就down了

    本文主要讲解linux 时间管理系统中的一个问题 背景:linux 时间管理,包含clocksource,clockevent,timer,tick,timekeeper等等概念 , 这些概念有机地组 ...

  9. rcu使用遇到问题汇总

    1.3.10内核,在项目中遇到一种情况,我们根据sk指针hash到一个cpu上,然后访问该cpu对应分配的一个数据区. 然后系统会偶尔crash掉,crash掉有两种情况,一种是cred的rcu回收时 ...

  10. 轻松月薪过万,NISP证书含金量有多重|NISP管理中心|网安伴|nisp

    nisp一级证书含金量 NISP一级证书是面向各个行业工作人员信息安全意识普及化和网络信息安全基础培训的国家级验证.持NISP一级证书可以从信息安全保密较高的单位得到加分.证书由中国信息安全测评中心授 ...