Natasha 4.0 探索之路系列(一) 概况

823f730a8fb69d0fdcaca0d6b5726e1b.png

简介

Natasha 是一个基于 Roslyn 的动态编译类库,它以极简的 API 完成了动态编译的大部分功能,使用它可以在程序运行时编译出新的程序集。

Natasha 允许开发人员直接使用 C# 代码即可编写运行时的功能,避免了 Emit 的学习、开发、维护的成本。

Natasha 的编译单元的基本输出是程序集,程序集加载在域中,使用该类库可以创建域,并在不同的域内创建新的功能,也支持可以卸载域。

Natasha 为开发人员提供了插件管理的功能,并内置解析依赖的功能,我们可以有针对性的加载和卸载插件及其依赖。

使用 Natasha 我们可以快速的实现映射/类库粘合/业务逻辑组装/动态代理/协议转换等等,使用 Natasha  需要一定的编程基础,有动态编译经验相关的实践。尽管 Natasha  可以输出详细日志,但是动态功能的开发本应该是逻辑畅通,代码规范的,如果你不能保证代码是畅通的,且没有动态编译的思维可以先找相关的文章进行学习。

项目链接地址: https://github.com/dotnetcore/Natasha

Natasha 的进化

Natasha 自 v3.0.0 版本之后,进行了比较大的革新,以下我列举一些比较重要的:

  • 移除对 .NET Standard2.0 / .NET Core 2.1-3.0 的支持,目前支持的版本为:.NET Core 3.1/.NET 5.0/.NET 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 已经在网友公司及我司得到了广泛应用,比如:客户端脚本定制,动态计分系统,低代码应用中的逻辑组装与编译, 类库中字符串到表达式树的转换,基于算法的高性能只读并发字典,忽略类库版本的代码粘合剂,实体映射,动态路由,动态 RPC, 动态定时任务等等。

Natasha 与其他技术

  • SG(Source Generetor)

首先来讲 Natasha 与 SG 有重叠的部分,但也有各自取代不了的地方。我认为比较好的组合是,SG 提供静态约束,Natasha 来提供动态实现。

  • AOT

Natasha 是尽可能覆盖全面的程序集和引用,剪裁需谨慎,另外 AOT 不会取代动态编译,只会平行发展。

未来规划

Natasha 完成了自己的核心任务,但它还有很长一段的路要走,期待大家的反馈。

后续 Natasha 还有一些方案需要调研,一些应用需要开发,例如:域的强制卸载方案,基于 ASP.NET 的动态开发框架,高度灵活的高性能实体映射库等。

下一篇将介绍 Natasha 的域组件与插件编程。

fb31a782943d69c7ea73273297566cad.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292262.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相信应该有百分九十的男生看见这个东西是这个状态吧?

1 8400亿人民币是什么概念&#xff1f;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 神奇的翻译&#xff08;素材来源豆瓣&#xff0c;侵删&#xff09;▼3 医生为什么喜欢把手背在后面呢&#xff1f;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 …

postman安装_Postman插件的应用与实战(二)

在postman插件的应用与实战(一)中&#xff0c;介绍了postman插件的安装&#xff0c;使用&#xff0c;collestion的创建以及应用&#xff0c;本小节中&#xff0c;我们来介绍postman结合newman和jenkins持续构建工具&#xff0c;来对postman中的接口测试进行统一的管理。关于new…

struts2:JSP页面及Action中获取HTTP参数(parameter)的几种方式

本文演示了JSP中获取HTTP参数的几种方式&#xff0c;还有action中获取HTTP参数的几种方式。 1. 创建JSP页面&#xff08;testParam.jsp&#xff09; <% page language"java" import"java.util.*" pageEncoding"utf-8"%> <% page isELIg…

HTTP—缓存

1. ETag HTTP 1.1中引入了ETag来解决缓存的问题。ETag全称是Entity Tag&#xff0c;由服务端生成&#xff0c;服务端可以决定它的生成规则。如果根据文件内容生成散列值。那么条件请求将不会受到时间戳的改动造成带宽浪费。下面是根据内容生成散列值的方法&#xff1a; 1 var g…

盖茨被逐出微软董事会真相曝光:长期跟员工搞地下情,27年婚姻中出轨不断,人设已崩...

全世界只有3.14 % 的人关注了爆炸吧知识转自&#xff1a;量子位作者&#xff1a;梦晨 鱼羊2020年3月&#xff0c;在比尔盖茨辞去微软董事会职务的时候&#xff0c;人们都在感慨一代互联网大拿&#xff0c;纷纷都到了交接班的时候。万万没想到&#xff0c;一年多之后&#xff0c…

Natasha 4.0 探索之路系列(二) 「域」与插件

域与ALC在 Natasha 发布之后有不少小伙伴跑过来问域相关的问题&#xff0c;能不能兼容 AppDomain、如何使用 AppDomain、为什么 CoreAPI 阉割了 AppDomain 等一系列的问题。今天答复一下&#xff1a;首先 AppDomain 作为程序集隔离容器的存在&#xff0c;是风靡了 .NET Framewo…

cake fork什么意思_Java7任务并行执行神器:Forkamp;Join框架

Fork/Join是什么&#xff1f;Fork/Join框架是Java7提供的并行执行任务框架&#xff0c;思想是将大任务分解成小任务&#xff0c;然后小任务又可以继续分解&#xff0c;然后每个小任务分别计算出结果再合并起来&#xff0c;最后将汇总的结果作为大任务结果。其思想和MapReduce的…

linux C语言之called object ‘maze’ is not a function or function pointer printf(“%d\t“, maze(i, j))

今天写广度优先搜索的时候出现了这个问题&#xff0c; 解决办法&#xff1a; 特么我傻逼了&#xff0c;明显是数组&#xff0c;我写成了mate(i, j),然后我改了写成了mate[i, j]; 特么我又傻逼了 改成mate[i][j] 就可以了

Greenplum 数据库架构分析

Greenplum 数据库是最先进的分布式开源数据库技术&#xff0c;主要用来处理大规模的数据分析任务&#xff0c;包括数据仓库、商务智能&#xff08;OLAP&#xff09;和数据挖掘等。自2015年10月正式开源以来&#xff0c;受到国内外业内人士的广泛关注。本文就社区关心的Greenplu…

Blog.Core高级进阶:共赴五年之约

读书破万卷&#xff0c;下笔如有神。佳著荐大家马上新年好呀&#xff0c;还有七天就是春节了&#xff0c;2022年是真真正正的到来了&#xff0c;老张打算在新的一年里&#xff0c;继续为开源社区做贡献&#xff0c;Blog.Core开源项目也正式进入第五个年头了&#xff0c;是时候作…

stringredistemplate设置过期时间_Redis的过期删除策略和内存淘汰机制

Redis的key可以设置过期时间&#xff0c;那是否意味着时间一到就会马上被删除呢&#xff1f;Redis的数据存储大小是有限的&#xff0c;假如内存不足Redis有什么应对策略呢&#xff1f;本篇文章将介绍一下Redis的过期策略和内存淘汰机制。1、redis的过期策略1.定时删除在设置key…

linux之怎么使vim永久显示行号

1、进入当前用户目录 2、输入下面命令 vim ~/.vimrc 3、退出保存 :x 4、用vim打开文件验证

java.util.ConcurrentModificationException异常

2019独角兽企业重金招聘Python工程师标准>>> <p> 今天遇到了一个小bug&#xff0c;在对ArrayList操作时出现了java.util.ConcurrentModificationException异常。原来是arrary在遍历时&#xff0c;是不能删除其中的对象的。 for(MediaFeedData item : Item…

eclipse中git插件配置 编辑

一、Eclipse上安装GIT插件EGit EGit插件地址&#xff1a;http://download.eclipse.org/egit/updates OK&#xff0c;随后连续下一步默认安装就可以&#xff0c;安装后进行重启Eclipse 二、在Eclipse中配置EGit 准备工作&#xff1a;需要在https://github.com 上注册账号 Prefer…

使用 C# 开发 Kubernetes 组件,获取集群资源信息

写什么呢前段时间使用 C# 写了个项目&#xff0c;使用 Kubernetes API Server&#xff0c;获取信息以及监控 Kubernetes 资源&#xff0c;然后结合 Neting 做 API 网关。体验地址 http://neting.whuanle.cn:30080/账号 admin&#xff0c;密码 admin123本篇文章主要介绍&#xf…

whitelabel error page什么意思_什么是RESTful API?总算能说清楚了

要弄清楚什么是RESTful API,首先要弄清楚什么是REST。REST -- REpresentational State Transfer&#xff0c;英语的直译就是“表现层状态转移”。如果看这个概念&#xff0c;估计没几个人能明白是什么意思。那下面就让我来用一句人话解释一下什么是RESTful:URL定位资源&#xf…

【转】Asp.net控件开发学习笔记整理篇 - 数据回传

最近一直在做MVC项目&#xff0c;对于WEBFORM 好像快忘记了。周末无聊&#xff0c;顺带看看他人的笔记。再次温习下。 复习大纲&#xff1a; 导航、页面生命周期及其它导论 一、服务器控件生命周期 二、控件开发基础 三、Asp.net服务端状态管理 四、Asp.net客户端状态管理 五、…

BZOJ2326 [HNOI2011]数学作业

首先&#xff0c;列方程 我们定义s[i] 10 ^ ((int) log(i)) 于是&#xff0c;f[i] (f[i - 1] * s[i] i) % p 反正总之就是个沙茶递推 然后我们来看优化。。。怎么感觉像矩阵乘法呢&#xff1f; 发现要按照log(i)即i的位数分类讨论&#xff0c;在相同位数的时候令矩阵为 s[i]…