动态编译库 Natasha 5.0 兼容版本发布
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 兼容版本发布的更多相关文章
- 基于roslyn的动态编译库Natasha
人老了,玩不转博客园的编辑器,详细信息转到:https://mp.weixin.qq.com/s/1r6YKBkyovQSMUgfm_VxBg 关键字:Github, NCC, Natasha,Ros ...
- QuantumTunnel:v1.0.0 正式版本发布
经过一段时间运行,代码已经稳定是时候发布正式版本了! v1.0.0 正式版本发布 对核心能力的简要说明: 支持协议路由和端口路由:QuantumTunnel:端口路由 vs 协议路由 基于Netty实 ...
- 动态线程池框架 DynamicTp v1.0.6版本发布。还在为Dubbo线程池耗尽烦恼吗?还在为Mq消费积压烦恼吗?
DynamicTp 简介 DynamicTp 是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为 动态调参.通知报警.运行监控.三方包线程池管理等几大类. 经过几个版本迭代,目前最新 ...
- 面向UI编程:ui.js 1.0 粗糙版本发布,分布式开发+容器化+组件化+配置化框架,从无到有的艰难创造
时隔第一次被UI思路激励,到现在1.0的粗糙版本发布,掐指一算整整半年了.半年之间,有些细节不断推翻重做,再推翻再重做.时隔今日,终于能先出来个东西了,这个版本很粗糙,主体功能大概能实现了,但是还是有 ...
- Apache Dolphinscheduler3.0.0-beta-1 版本发布,新增FlinkSQL、Zeppelin任务类型
导读:近日,Apache Dolphin Scheduler 迎来了 3.0.0-beta-1 版本的正式发布.新版本主要针对 3.0.0-alpha 进行了代码和文档的修复,并引入了部分的功能,如支 ...
- LogDashboard 1.0.4 版本发布
LogDashboard 1.0.4 版本 有关LogDashboard的介绍请看这里.logDashboard已经发布了1.0.4版本 有关这个版本的详细变化可以在Github上的里程碑上查看 支持 ...
- ML.NET 0.9 版本发布---.net下的机器学习引擎
欢迎来到 2019年!在过去的9个月里, 我们一直在为ML.NET添加新的特征和改进相关功能.在提交1.0版本之前,我们将专注于包的整体稳定性并对API进行不断优化, 扩大测试的覆盖面并对开发文档进行 ...
- NHibernate 1.0 Released 版本发布了
NHibernate is a port of Hibernate to the .NET platform. Hibernate is the leading open-source object- ...
- ScutSDK 0.9版本发布
ScutSDK简介: ScutSDK是和Scut游戏服务器引擎,简化客户端开发的配套SDK,她彻底打通了Scut开源游戏服务器引擎与客户端引擎(如Cocos2d-x/Quick-x/Unity3D)项 ...
随机推荐
- Calendar类介绍_获取对象的方式和Calendar类的常用成员方式
java.util.Calendar是日历类,在Date后出现,替换掉了许多Date方法.该类将所有可能用到的时间信息封装为静态成员变量,方便获取.日历类就是方便获取各个时间属性的. Calendar ...
- 清北学堂 2020 国庆J2考前综合强化 Day4
目录 1. 题目 T1 写字符串 题目描述 Sol T2 神奇的数 题目描述 Sol T3 珠子染色 题目描述 Sol T4 病毒扩散 题目描述 Sol 算法 -- 图论 1. 题目 T1 写字符串 ...
- 一文搞懂什么是kubernetes Service
1.什么是Service? 在kubernets中,Pod是应用程序的载体,Pod你可以想象成就是容器,为动态的一组Pod提供一个固定的访问入口,它是以一种叫ClusterIP地址来进行标识,而Clu ...
- MySQL8.0错误日志Error log
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 理论知识 错误日志内容 错误日志包含mysqld启动和关闭的时间信息,还包含诊断消息,如服务器启动和关闭期间以及服务器运行 ...
- 5. MGR管理维护 | 深入浅出MGR
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 1. 切换主节点 2. 切换单主/多主模式 3. 添加新节点 4. 删除节点 5. 异常退出的节点重新加回 6. 重 ...
- HDFS核心原理
HDFS 读写解析 HDFS 读数据流程 客户端通过 FileSystem 向 NameNode 发起请求下载文件,NameNode 通过查询元数据找到文件所在的 DataNode 地址 挑选一台 D ...
- 搞定面试官 - 你可以介绍一下在 MySQL 中,哪些情况下 索引会失效嘛?
大家好,我是程序员啊粥,前边给大家分享了 *MySQL InnoDB 索引模型 在 MySQL InnoDB 中,为什么 delete 删除数据之后表数据文件大小没有变 如何计算一个索引的长度 如何查 ...
- 字符串KMP——用途广泛的字符串匹配算法 + 扩展KMP——特殊定义的字符串匹配
引 入 引入 引入 " SY 和 WYX 在看毛片.(几 毛 钱买到的动作 片,毛 片) WYX 突然想回味一个片段,但是只记得台词里面有一句挺长的 " ∗ ∗ ∗ ∗ **** ...
- mysql 重复执行创建表、新增字段脚本
#bigint 可重复执行创建表脚本 1 Create Table If Not Exists `库名`.`表名`( 2 字段列表 3 ) ENGINE=InnoDB DEFAULT CHARSET= ...
- 在 node 中使用 jquery ajax
对于前端同学来说,ajax 请求应该不会陌生.jquery 真的ajax请求做了封装,可以通过下面的方式发送一个请求并获取相应结果: $.ajax({ url: "https://echo. ...