Natasha 4.0 探索之路系列(一) 概况
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 的域组件与插件编程.
Natasha 4.0 探索之路系列(一) 概况的更多相关文章
- Natasha 4.0 探索之路系列(二) "域"与插件
域与ALC 在 Natasha 发布之后有不少小伙伴跑过来问域相关的问题, 能不能兼容 AppDomain, 如何使用 AppDomain, 为什么 CoreAPI 阉割了 AppDomain 等一系 ...
- Natasha 4.0 探索之路系列(三) 基本的动态编译
Natasha 的设计 动态编译 Roslyn 为开发者提供了动态编译的接口, 允许我们以 C# 代码来编写 Emit 或 表达式树生成的程序集, 但是完成一个编译需要诸多步骤, 用户参与的操作也很多 ...
- Natasha 4.0 探索之路系列(四) 模板 API
Natasha 模板 Natasha 在编译单元的基础上进行了封装整理, 并提供了多种模板帮助开发者构建功能. 使用此篇的 API 前提是您对 C# 非常熟悉, 对系统的一些类型足够了解. 据此 Na ...
- 【Android Studio探索之路系列】之六:Android Studio加入依赖
作者:郭孝星 微博:郭孝星的新浪微博 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.co ...
- WCF 4.0 进阶系列 -- 随笔汇总
WCF4.0 进阶系列–前言 WCF4.0 进阶系列--第一章 WCF简介 WCF4.0进阶系列--第二章 寄宿WCF服务 WCF4.0进阶系列--第三章 构建健壮的程序和服务 WCF4.0进阶系列- ...
- 【转】WF4.0实战系列索引
转自:http://www.cnblogs.com/zhuqil/archive/2010/07/05/wf4-in-action-index.html 此系列的工作流文件案例比较多点,实用性好. W ...
- PBOC2.0安全系列之—脱机认证之动态数据认证(DDA)
动态数据认证: 一,什么是动态数据认证(DDA) 由于上篇<< PBOC2.0安全系列之—脱机认证之静态数据认证(SDA)>>已经对静态数据认证部分做了详细的分析,一些基本知识 ...
- Vue2.0 探索之路——生命周期和钩子函数的一些理解
前言 在使用vue一个多礼拜后,感觉现在还停留在初级阶段,虽然知道怎么和后端做数据交互,但是对于mounted这个挂载还不是很清楚的.放大之,对vue的生命周期不甚了解.只知道简单的使用,而不知道为什 ...
- Vue2.0 探索之路——生命周期和钩子函数的一些理解 - JS那些事儿
在使用vue一个多礼拜后,感觉现在还停留在初级阶段,虽然知道怎么和后端做数据交互,但是对于mounted这个挂载还不是很清楚的.放大之,对vue的生命周期不甚了解.只知道简单的使用,而不知道为什么,这 ...
随机推荐
- Java abstract 抽象类 和interface接口的异同点
abstract 抽象类 和interface接口的异同点 相同点: 抽象类和接口都不能实例化,他们都位于继承树顶端,被其他类实现和继承 都可以包含抽象方法,实现接口或者继承抽象类的非抽象类(普通类) ...
- 动态导入模块__import__("str") importlib标准库
解释器内部使用的为__import__('str') #!/usr/bin/env python # Author:Zhangmingda print('我是aa类 ') #被import的时候就执行 ...
- generating project in interactive mode
解决方案:加个参数 -DarchetypeCatalog=internal 让它不要从远程服务器上取catalog
- MyBatis学习(五)MyBatis-开启log4j日志
1.前言 Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件,甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等 ...
- 【九度OJ】题目1015:还是A+B 解题报告
[九度OJ]题目1015:还是A+B 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1015 题目描述: 读入两个小于10000的正整 ...
- 【LeetCode】886. Possible Bipartition 解题报告(Python)
[LeetCode]886. Possible Bipartition 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu ...
- 【剑指Offer】旋转数组中的最小数字 解题报告(Python)
[剑指Offer]旋转数组中的最小数字 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- 【LeetCode】522. Longest Uncommon Subsequence II 解题报告(Python)
[LeetCode]522. Longest Uncommon Subsequence II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemin ...
- 【LeetCode】334. Increasing Triplet Subsequence 解题报告(Python)
[LeetCode]334. Increasing Triplet Subsequence 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode. ...
- python-mysql-replication原理分析
源码地址:https://github.com/noplay/python-mysql-replication 文件解析: ├── binlogstream.py ├── bitmap.py ├── ...