抽丝剥茧!Source Generators原理讲解

前言

前段时间,我们已经用Source Generators实现了好多功能,比如AutoMapper、API最佳实践。

你看完那些实现代码,是不是还有点云里雾里!

Source Generators到底是怎么做到的?

基础知识

Source Generators是编译过程的一部分,它以编译树作为输入,通过分析代码,动态生成文件并把它们加入到编译过程中:

需要注意的是,你只能添加一些东西到代码,但不能改变现有的代码。

为了使用Source Generators,你必须创建.Net Standard项目,并引用nuget包Microsoft.CodeAnalysis.CSharp 3.8.0或以上版本。

基本的实现代码如下,你必须实现ISourceGenerator接口,并且用GeneratorAttribute标注:

[Generator]
public class DemoSourceGenerator : ISourceGenerator
{public void Execute(GeneratorExecutionContext context){throw new NotImplementedException();}public void Initialize(GeneratorInitializationContext context){throw new NotImplementedException();}
}

生成器执行上下文

主要生成过程通过Execute方法执行。

Execute传递一个GeneratorExecutionContext实例,下列是实例常用的属性和方法:

  • AdditionalFiles 获取当前编译项目文件中的所有AdditionalFiles标签

  • Compilation 编译上下文,最重要的对象

  • AddSource 向编译器加入代码,最重要的方法

语法树

通过GeneratorExecutionContext.Compilation我们可以获得编译上下文,有了这个对象,你就可以访问当前编译项目的整个语法树(SyntaxTree)。

那什么是语法树呢?

首先,安装.NET Compiler Platform SDK

然后,在VS中打开“视图”->“其他窗口”->“Syntax Visualizer”。

可以看到,语法树是一个树形结构,和每一行代码一一对应

语法树包含三种类型的项——node、token和trivia。

比如public class Class1 { }整体是ClassDeclaration node,下级的Class1则是ClassKeyword token, 而紧跟的空格则是Whitespace trivia

因此,只要我们遍历语法树,即可拿到编译中的任何代码。

Demo

现在把上面的综合起来,我们就可以开发Source Generators功能了:

public void Execute(GeneratorExecutionContext context)
{//获取第一个附加文件内容,用作代码模板var template = context.AdditionalFiles.First().GetText().ToString();//获取第一个类名var className = context.Compilation.SyntaxTrees.SelectMany(p => p.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>()).First().Identifier.Text;// 替换文本生成代码// 你也可以使用模板引擎或者StringBuilder拼接出代码var source = template.Replace("{Class}", className);// 向编译过程添加代码文件context.AddSource("Demo", SourceText.From(source, Encoding.UTF8));
}

在待编译的项目中添加一个附加文件

<ItemGroup><AdditionalFiles Include="template.txt"  />
</ItemGroup>

template.txt的文件内容如下:

using System;namespace ClassLibrary1
{public static class Demo{public static void SayHello(){Console.WriteLine("Hello {Class}!");}}
}

编译后,可以看到生成如下代码:

结论

希望我已经描述清楚了使用Source Generators的整个过程。

期待你用它开发出更多更好的功能!

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

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

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

相关文章

GPON技术概述

GPON技术转载自《电子发烧友》。文章链接请见&#xff1a;http://www.elecfans.com/article/88/171/2009/2009050556028.htmlGPON技术详述介绍GPON 技术之前&#xff0c;先介绍目前也被应用的另一种PON 技术“EPON”。1&#xff0e;EPON技术介绍EPON 又名 GEPON&#xff0c;是由…

linux中断处理汇编入口,Linux中断处理体系结构分析(一)

中断也是一种异常&#xff0c;之所以把它单独的列出来&#xff0c;是因为中断的处理与具体的开发板密切相关&#xff0c;除一些必须、共用的中断(比如系统时钟中断、片内外设UART中断)外&#xff0c;必须由驱动开发者提供处理函数。内核提炼出中断处理的共性&#xff0c;搭建一…

没有违反GPL,他们真的给了源码

文 | Travis出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;【前情回顾】国内智能设备制造商 UMIDIGI 因违反 GPLv2 协议引发争议&#xff0c;并告知开发者“想要源码上门自取”。而后&#xff0c;知名科技博主 Naomi Wu&#xff08;机械妖姬&#xff09…

有朋友问我为什么这么帅

1 2 重庆的朋友告诉我这是微辣3 我就说我只是虚胖&#xff0c;这下你相信了吧&#xff1f;4 这明明就是打情骂俏好嘛5 这还是那个平常瓶盖都拧不开的女孩子吗6 被一个机器人撩到了&#xff01;7 这是什么原理&#xff1f;你点的每个赞&#xff0c;我都认真当成了喜欢

python安装详细步骤mac_Mac安装python3的方法步骤

Python有两个版本&#xff0c;一个是2.x版&#xff0c;一个是3.x版&#xff0c;这两个版本是不兼容的。 现在 Mac 上默认安装的 python 版本为 2.7 版本&#xff0c;若 安装 新版本需要 通过 该地址进行下载&#xff1a; https://www.python.org/ftp/python/3.5.0/python-3.5.0…

在Excel中实现下拉列表选择录入

我们在用Excel录入表格数据时&#xff0c;常常会遇到某列数据的值只在几个固定值中选择一个的情况&#xff0c;比如&#xff1a;人的性别列只可能录入男或女&#xff0c;对学历列只可能录入高中、大专、本科、研究生之一等。遇到这类数据&#xff0c;如果我们手工录入&#xff…

你吃的瓜子仁,真是老奶奶磕出来的?!

全世界只有3.14 % 的人关注了爆炸吧知识本文转载自微信公众号一只学霸&#xff08;ID&#xff1a;bajie203&#xff09;萌萌不是挺爱吃瓜子仁吗有次他吃的时候大毛在旁边看着看着突然想到一个问题吓得我反思了一下自己是怎么和他们考上同个学校的没思考出来吓得我给大家写了这篇…

持续20年,一场威胁Linux存亡的诉讼终结束

文 | 局长出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;一场持续将近 20 年、曾被认为会威胁 Linux 存亡的诉讼终于迎来了尾声。这场诉讼开始于 2003 年&#xff0c;不过其背后的事件最早可追溯到 1998 年。当时 IBM 和 Santa Cruz Operation&#xff…

shell grep 变量_老司机给出的关于 shell 脚本的8个建议,必收!

这八个建议&#xff0c;来源于键者几年来编写 shell 脚本的一些经验和教训。事实上开始写的时候还不止这几条&#xff0c;后来思索再三&#xff0c;去掉几条无关痛痒的&#xff0c;最后剩下八条。毫不夸张地说&#xff0c;每条都是精挑细选的&#xff0c;虽然有几点算是老生常谈…

不是说好一起长大的吗?

1 仿佛闻到了嫉妒的味道&#xff01;2 阿拉&#xff1a;不是说好一起长大的吗&#xff1f;3 还有这么小的菠萝蜜&#xff1f;&#xff1f;4 你以为它是个橘子其实它并不是5 当我吃到自己喜欢吃的东西时……6 以后吃完小龙虾&#xff0c;千万别扔&#xff0c;有妙用7 这是啥玩意…

javascript:设置URL参数的方法,适合多条件查询

适用场景&#xff1a;多条件查询情况&#xff0c;如下图所示&#xff1a; 通过设置URL参数&#xff0c;再结合数据源控件设置的RUL参数&#xff0c;就能进行简单的多条件查询了。 javascript函数&#xff1a; <mce:script type"text/javascript"><!-- //设置…

SQL点滴19—T-SQL中的透视和逆透视

原文:SQL点滴19—T-SQL中的透视和逆透视透视 今天抽一点时间来看看透视和逆透视语句&#xff0c;简单的说就是行列转换。假设一个销售表中存放着产品号&#xff0c;产品折扣&#xff0c;产品价格三个列&#xff0c;每一种产品号可能有多种折扣&#xff0c;每一种折扣只对应一个…

Magicodes.IE 2.5.5.3发布

2.5.5.32021.08.27修复Append方式导出多个sheet时&#xff0c;发生“Tablename is not unique”错误&#xff0c;具体见#299。2.5.5.22021.08.24添加对Abp模块的包装&#xff0c;具体见#318。Magicodes.IE.Excel.Abp&#xff08;MagicodesIEExcelModule&#xff09;注册IExcelE…

C语言阿斯码,木叶四位上忍设定各不相同,网红负责秀操作,她只需要美就够了...

原标题&#xff1a;木叶四位上忍设定各不相同&#xff0c;网红负责秀操作&#xff0c;她只需要美就够了木叶四位上忍设定各不相同&#xff0c;网红负责秀操作&#xff0c;她只需要美就够了说道忍界网红&#xff0c;那一定就是卡卡西了。卡卡西在《火影》当中的表现俘获了大批小…

80岁COBOL码农:扶我起来,这个bug我会修!

95&#xff05;的 ATM 交易通过 COBOL 程序&#xff0c;80&#xff05;的现场交易依赖于它们&#xff0c;超过 40&#xff05;的银行仍然使用 COBOL 作为其系统的基础。由于年轻人懂 COBOL 的比较少&#xff0c;美国康涅狄格州劳工部正在召回经验丰富的退休 COBOL 人员。来源&a…

小心使用宏

开发过程中&#xff0c;会经常使用宏定义&#xff0c;偶尔还会碰到重复定义的宏&#xff0c;有些时候会造成不良影响。 见如下例子&#xff1a; Test.h #ifndef GUARD_TEST_H #define GUARD_TEST_H class CTest { public: CTest(); virtual ~CTest(); void Display(void); publ…

数据资产纳入国资保值增值考核

首先是国资云近期横空出世&#xff0c;国资云的推广预示着党政及国企未来将坚持私有云技术路线。从天津、四川等省市国资云平台的建设方式来看&#xff0c;未来党政及国企部门的业务系统上云将坚持私有云的技术路线&#xff0c;由此可能对未来国内云计算市场带来深远影响。国资…

iPhone5:4G是否进入主流的风向标?

当业内的目光不约而同地集中到苹果即将发布的iPad2的时候&#xff0c;按照惯例&#xff0c;苹果的另一款重量级产品iPhone5也会在今年登场。近日&#xff0c;国外有预测称&#xff0c;苹果的iPhone5可能会不支持 4G网络&#xff0c;这多少令业内感到意外和失望&#xff0c;并由…

一滴水从高处落下来,会不会砸死人?

全世界只有3.14 % 的人关注了爆炸吧知识有一个相当古老的段子是这么说的&#xff1a;为了涨姿势&#xff0c;我加入一个物理博士群&#xff0c;见到有人问&#xff1a;一滴水从很高的地方落下来&#xff0c;会不会弄死人&#xff1f;群里一下就热闹起来&#xff0c;各种公式&am…

给ubuntu换个图标主题(icon theme)

2019独角兽企业重金招聘Python工程师标准>>> 对于linux mint&#xff0c; http://linuxmint-art.org/?xcontentmode8325给出了很多icon主题。 安装方法有下面几种&#xff1a; 1、使用PPA 2、将解压后的icon主题目录放到 /usr/share/icons目录下。 3、将解压后的i…