Natasha 4.0 探索之路系列(三) 基本的动态编译

013eb30c174283b60b91e1b540d9482f.png相关文章

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

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

Natasha 的设计

动态编译

Roslyn 为开发者提供了动态编译的接口,允许我们以 C# 代码来编写 Emit 或 表达式树生成的程序集,但是完成一个编译需要诸多步骤,用户参与的操作也很多,例如: 格式化整理语法树,创建编译选项,填充对应的引用程序集来支持语义检查和编译,控制输出流等。其中除了第一个语法树相对简单,后面都需要开发者摸索完成。毕竟 Roslyn 的文档不全,甚至关于它的文档散落在其他边角章节,比七龙珠都散。那么在这种情况下使用 Natasha 无疑是非常好的选择。

Natasha 的便捷之处

Natasha 自发版以来,便集成有引用管理,全局 Using 管理,域管理,这让开发者极大的减少了开发前的准备工作,在便捷编译过程中,Natasha 支持引用覆盖,Using 覆盖,编译流到域的输出,有了这三大保证,开发者可更多的关注于动态功能逻辑的开发。新版 Natasha 新增了语义过滤委托 API 以方便用户根据语义信息定制/重组自己的语法树,并提供方法支持开发者管理引用版本,另外保证了3种流的对外输出,即

  • dll : 程序集输出文件

  • pdb : 元数据调试信息

  • xml : 元数据结构及注释

整个编译过程中将会分3阶段抛出异常:

  1. 语法构建阶段,如果出错则抛出异常;

  2. 编译阶段,如果编译失败则会抛出异常;

  3. 元数据转换阶段,有些 API 是支持从 Assembly 到其他元数据获取和转换的,转换失败则抛出异常。

Natasha 基本编译单元

Natasha 的基本编译单元为 AssemblyCSharpBuilder ,该单元整合了编译流程所需要的基本功能,相比 Natasha 的模板而言,它则是轻量级,底层的工作单元。以下是使用方法:

首先引入 DotNetCore.Natasha.CSharp

最基本的编译操作
//Natasha 预热
NatashaInitializer.Preheating(/*...引用添加过滤器...例如:(item,name) => name!.Contains("IO")*/);string code = @"public class A{public string Name=""HelloWorld"";}";//在花括号范围内圈定域,using 内的方法锁定了域的作用范围.
//Natasha 所有关于 Name 的 Api 如果不指定,默认为 GUID.
using (DomainManagement.Create(domainName)/Random().CreateScope())
{AssemblyCSharpBuilder builder = new( /*....assenblyName....*/ );builder.Add(code);var type = builder.GetTypeFromShortName("A");  //...do sth..。
}//手动指定域
AssemblyCSharpBuilder builder = new();
builder.Domain = DomainManagement.Random();
builder.Add(code);
var assembly = builder.GetAssembly();  
//...do sth..。//直接定位到委托
string code = @"public class A{public string Name=""HelloWorld""; public static string Get(){  return (new A()).Name; }}";
using (DomainManagement.Create("myDomain").CreateScope())
{AssemblyCSharpBuilder builder = new("myAssembly");builder.Add(code);var func = builder.GetDelegateFromShortName<Func<string>>("A","Get");Assert.Equal("HelloWorld",func()); // √
}
其他 API
//设置输出 dll 文件路径
builder.SetDllFilePath(mydll);
//设置输出 pdb 文件路径
builder.SetPdbFilePath(mypdb);
//设置输出 xml 文件路径
builder.SetXmlFilePath(myxml);
//使用 Natasha 自带的输出路径(请在域和程序集名确定之后调用).
builder.UseNatashaFileOut();//配置编译选项
builder.ConfigCompilerOption(opt=>opt);
//配置语法树选项
builder.ConfigSyntaxOptions(opt=>opt);//给编译单元添加语义过滤
builder.AddSemanticAnalysistor();
//启/禁用语义过滤
builder.Enable/DisableSemanticCheck();//添加日志事件
builder.LogCompilationEvent += (log) => { if(log.HasError) Console.WriteLine(log.ToString()); };//编译事件
builder.CompileSucceedEvent //编译成功触发事件
builder.CompileFailedEvent //编译失败触发事件//引用行为与程序集加载行为控制
var assembly = builder//委托过滤: 如果发现默认域的引用与定制域中的引用有同名情况,则进入委托处理。返回一个枚举结果给程序处理.//PassToNextHandler 结果表示将进入到引用版本行为控制继续处理.CompileWithReferencesFilter((defaultAssemblyName,domainAssemblyName)=> LoadVersionResultEnum.PassToNextHandler)//引用行为控制,None/UseHighVersion/UseLowVersion/UseDefault(默认使用)/UseCustom 四种控制方法.CompileWithReferenceLoadBehavior(referenceLoadBehavior)//程序集编译成功后,在域中加载的行为控制,默认为 LoadBehaviorEnum.None (全加载);.CompileWithAssemblyLoadBehavior(LoadBehaviorEnum.UseDefault).GetAssembly();

注意: 主域的引用文件和自己创建域的引用文件可能存在同名,但不同版本,此时编译需要 CompileWithReferenceLoadBehavior 来控制引用加载的行为,举例:RefA(v1.0) 和 RefA(v2.0) 相比,v2.0 中比 v1.0 多了几个功能,几个类、几个接口……那么在管理引用的时候,你就要根据自身的代码情况进行管理,比如你的代码用到了 v2.0 的新类,新功能,那么就要屏蔽掉 v1.0。

覆盖全局 using
//-------------------主域 using -------------------- 定制域 using ------------------------------- 代码脚本 ---------------
string code = DefaultUsing.UsingScript +  builder.Domain.UsingRecorder.ToString() + "namespace{ public class xx....。}";

域中的 UsingRecorder 会记录编译之后产生的 using,自动管理。

结尾

大家在使用动态编译时,要尽可能做到“隔离”,一旦依赖和引用版本多了,对于动态开发来讲,就是一场灾难。以上是使用 Natasha 关于动态编译的最基本使用方法,下一篇将讲解 Natasha 高级 API 的使用。

a0018d62250c491a6f1bc8b75f5157f3.png

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

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

相关文章

〖Windows〗Linux的Qt程序源码转换至Windows平台运行,编码的解决

在中国大陆&#xff0c;Windows默认的编码是gb2312&#xff0c;而Linux是UTF8&#xff1b; 多数情况下&#xff0c;把Linux上的程序转换至Windows上运行需要进行编码转换才能正常显示&#xff1b; 而其实大可以不必的&#xff0c;同样&#xff0c;文件使用的依然是UTF-8&#x…

使用WebSocket绕过广告屏蔽插件

2019独角兽企业重金招聘Python工程师标准>>> 现在网络上的广告真的是无所不用其极&#xff0c;在网上冲浪&#xff0c;稍不留神&#xff0c;随时随地都会碰上广告&#xff0c;于是广告屏蔽这个需求&#xff0c;就应运而生了。古语云&#xff0c;道高一尺魔高一丈。今…

linux c头文件#include<sys/types.h>和#include<fcntl.h>头文件总结

#include<sys/types.h>的介绍 是Unix/Linux系统的基本系统数据类型的头文件&#xff0c;含有size_t&#xff0c;time_t&#xff0c;pid_t等类型。linux编程中经常用到的头文件。 clock_t 表示系统时间&#xff08;以时钟周期为单位&#xff09;。   dev_t 用于设备号…

vba怎么安装_学VBA,这些最基础的概念一定要知道

说说VBA的那些事儿VBA是什么&#xff1f;很多使用Excel的人经常会看到这三个字母&#xff0c;那么VBA到底是什么呢&#xff1f;长得神似VB的它到底是干什么的&#xff1f;相信很多人都会有这样的问题&#xff0c;今天就和大家说说有关VBA的那些事儿。1 VBA到底是什么VBA的全称&…

你好骚啊......

1 世贤和品如的结婚照是用当年潘粤明和董洁的结婚照PS的......&#xff08;你好骚啊&#xff09;▼2 还挺有耐心的呢...▼3 这是打算铁定要赢了&#xff01;▼4 请打钱&#xff01;▼5 停车场停猫场&#xff1f;▼6 你的养母&#xff1a;粉红豹、跳跳鱼已上线▼7 这是什么…

演示:使用Sniffer统计与分析流量

演示&#xff1a;使用Sniffer统计与分析流量Sniffer是统计与分析网络数据流量的一个很好的选择。因为Sniffer的“混杂”模式会接收到同一个物理网络内的所有数据帧&#xff0c;无论是广播帧还是发送到一个具体地址的数据帧。如果需要Sniffer监听到所处物理网络不同的数据帧&…

CSS3之阴影

CSS3中新增属性-阴影&#xff0c;可以做出很多漂亮的效果。 文字阴影text-shadow text-shadow属性值的顺序&#xff1a; text-shadow: h-shadow v-shadow blur color; 参数分别表示水平阴影位置&#xff0c;垂直阴影位置&#xff0c;模糊半径&#xff0c;阴影颜色。 一个栗子&a…

推荐搞IT的你读读《软件随想录》

《软件随想录&#xff08;Joel on Software&#xff09;》&#xff0c;这是我多年前看的一本书&#xff0c;也是对我影响很大大的一本书。这不是一本讲软件技术的书&#xff0c;但跟技术强相关&#xff0c;推荐给朋友们读一下。这本书严格来讲&#xff0c;不是作者专门写的书&a…

linux c中的文件描述符与打开文件之间的关系

转载请说明出处&#xff1a;http://blog.csdn.net/cywosp/article/details/38965239 1. 概述在Linux系统中一切皆可以看成是文件&#xff0c;文件又可分为&#xff1a;普通文件、目录文件、链接文件和设备文件。文件描述符&#xff08;file descriptor&#xff09;是内核为了高…

spss练习数据_读硕博,为你推荐5本最实用的SPSS数据统计书

SPSS (Statistical Product and Service Solutions&#xff09;,是由IBM公司所推出的一系列用于统计学分析运算、数据挖掘、预测分析和决策支持任务的软件产品。SPSS的基本功能包括数据管理、统计分析、图表分析、输出管理等等&#xff0c;也有专门的绘图系统&#xff0c;可以根…

她半年内举报了755篇问题论文,专挑中国“下手”?还牵扯到北大副校长.........

全世界只有3.14 % 的人关注了爆炸吧知识是挑刺还是打假&#xff1f;2020年7月23日&#xff0c;海外一家学术打假网站PubPeer曝出北京大学常务副校长、北大医学部主任、中国工程院院士詹启敏25篇论文涉嫌学术造假。这25篇论文的发表时间在1998年至2019年&#xff0c;贯穿詹启敏从…

C#获取用户客户端系统版本设备名称浏览器

先看效果使用Neget引用包UAParser项目的github &#xff1a;https://github.com/ua-parser/uap-csharpusing UAParser;...string uaString "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 …

ABP vNext微服务架构详细教程——简介

简介该系列文章主要展示ABP vNext框架在微服务架构下的用法&#xff0c;提供一套可落地的技术实现思路&#xff0c;并演示各服务在Kubernetes下的部署方案。基础概念ABP vNext基于ASP.NET Core的应用框架&#xff0c;是.Net主流应用开发框架之一。提供基于模块化的灵活项目模板…

电脑怎么测试硬盘的读写速度_两块硬盘合二为一,电脑读写翻倍?这样的“好事”你必须得了解...

近日&#xff0c;技嘉在旗下顶级的B550 AORUS MASTER主板上做了一次PCIe4.0固态阵列测试&#xff0c;由于该款主板支持3个PCIe4.0的M.2固态硬盘&#xff0c;所以这次的测试为3块PCIe4.0固态组建RAID0&#xff0c;来进行读写测试。常见的PCIe3.0x4的固态硬盘的读写速度一般在250…

C# 动态创建控件时注册Name属性

动态创建控件1. 容器控件 .RegisterName("Name",要注册的控件) //注册控件2. 容器控件 .FindName("Name") as 控件类型 //找到控件并转换成相应类型注意仅通过控件.Name来设置是不能通过FindName来找到控件的&#xff0c;必须注册动态删除控件1. 容器控件…

java配置运行环境和配置

2019独角兽企业重金招聘Python工程师标准>>> 1&#xff1a;准备好下载的java。开始安装 2&#xff1a;第一次蹦出安装路径设置为&#xff08;D:\java\jdk&#xff09;。不要设置下图样式设置路径! 3:jdk安装完成后会再弹出如下窗口&#xff0c;让你选择独立的jre的安…

SQL Server 的锁定和阻塞

本帖提供两种做法&#xff0c;可避免在 SQL Server 事务锁定时产生的不正常或长时间阻塞&#xff0c;让用户和程序也无限期等待&#xff0c;甚至引起 connection pooling 连接数超过容量。 所谓的「阻塞」&#xff0c;是指当一个数据库会话中的事务&#xff0c;正在锁定其他会话…

结构体数组排列_学习RTOS(3)数据结构

在 FreeRTOS 中存在着大量的基础数据结构列表和列表项的操作&#xff0c;列表和列表项是直接从 FreeRTOS 源码注释中的 list 和 list item 翻译过来的&#xff0c;其实就是对应我们 C 语言当中的链表和节点&#xff0c;在后续的讲解&#xff0c;我们说的链表就是列表&#xff0…