学习Source Generators之IncrementalValueProvider
前面我们使用了IIncrementalGenerator来生成代码,接下来我们来详细了解下IIncrementalGenerator的核心部分IncrementalValueProvider。
介绍
IncrementalValueProvider是基于管道的模式,将我们需要的数据进行处理转换后传递给SourceOutput。
目前官方提供可用的Providers有如下几种:
- CompilationProvider
- AdditionalTextsProvider
- AnalyzerConfigOptionsProvider
- MetadataReferencesProvider
- ParseOptionsProvider
实操
接下来我们来使用AdditionalTextsProvider来学习IncrementalValueProvider的运行方式。
创建项目
首先创建LearnIncrementalValueProvider的控制台程序和LearnIncrementalValueProvider.Analysis的netstandard2.0类库两个项目。

按照前面HelloWorld项目的项目配置进行配置和引用。
添加LearnIncrementalValueProviderGenerator
在LearnIncrementalValueProvider.Analysis中添加LearnIncrementalValueProviderGenerator继承并实现IIncrementalGenerator接口。
using Microsoft.CodeAnalysis;
using System;
using System.Diagnostics;
namespace LearnIncrementalValueProvider.Analysis
{
[Generator]
public class LearnIncrementalValueProviderGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
Debugger.Launch();
var additionalTextsProvider = context.AdditionalTextsProvider;
context.RegisterSourceOutput(additionalTextsProvider, (ctx, additionalTexts) =>
{
var path = additionalTexts.Path;
var text = additionalTexts.GetText(ctx.CancellationToken);
});
}
}
}
在实现的代码中,获取到AdditionalTextsProvider,并直接传递给RegisterSourceOutput,并在委托方法中直接获取AdditionalTextsProvider的文件路径以及文本内容。
在方法中加入Debugger.Launch();方便调试。
添加文件和调试
在控制台程序中,添加一个Files目录。往里面塞入一个swagger.json文件。
此时直接调试会发现,断点并不会进入到RegisterSourceOutput的委托中。

这是因为AdditionalTextsProvider并没有找到任何需要加载的文件。
我们需要在控制台程序的项目文件中添加AdditionalFiles,指定需要监听的文件。
<ItemGroup>
<AdditionalFiles Include="Files/*" />
</ItemGroup>
添加AdditionalFiles后,在调试一次。

可以看到断点成功进来了。并且可以看到获取的文件路径以及文件的文本内容。

多个文件
在Files目录中添加一个txt文件。并写入文本HelloWorld

然后再调试一次。可以发现,每一个文件都会单独执行一次委托的方法。

过滤文件
当我们只需要其中一种类型的文件的时候,我们可以通过Where来进行过滤筛选。

通过Debugger.Log可以发现,只输出了json的文件路径。

处理数据
可以使用Select来处理我们的数据,比如这里我只获取文件名称。通过Debugger.Log可以看到输出了两个文件名称。

集合
如果不想多次处理文件的话,可以使用Collect方法,直接把多个文件合并在一起。

这里可以看到,使用Collect,2个文件可以同时处理。
组合多个IncrementalValueProvider
除了对单个IncrementalValueProvider进行处理外,我们还可以组合不同的IncrementalValueProvider。
比如将CompilationProvider和AdditionalTextsProvider组合起来。
使用Combine方法。

可以看到 paris的Right和Left分别是CompilationProvider和AdditionalTextsProvider两种类型。
结语
以上就是IncrementalValueProvider比较常用的方式。通过这些操作可以灵活的实现我们的代码生成逻辑。
当然还有其他的IncrementalValueProvider,这里就不都写出来了。其他的可以自己实操玩起来~
本文代码仓库地址https://github.com/fanslead/Learn-SourceGenerator
学习Source Generators之IncrementalValueProvider的更多相关文章
- 基于 Source Generators 做个 AOP 静态编织小实验
0. 前言 上接:用 Roslyn 做个 JIT 的 AOP 作为第二篇,我们基于Source Generators做个AOP静态编织小实验. 内容安排如下: source generators 是什 ...
- .NET初探源代码生成(Source Generators)
前言 Source Generators顾名思义代码生成器,可进行创建编译时代码,也就是所谓的编译时元编程,这可让一些运行时映射的代码改为编译时,同样也加快了速度,我们可避免那种昂贵的开销,这是有价值 ...
- 使用 MVVM Toolkit Source Generators
关于 MVVM Toolkit 最近 .NET Community Toolkit 发布了 8.0.0 preview1,它包含了从 Windows Community Toolkit 迁移过来的以下 ...
- PHP的学习--生成器Generators
生成器总览 (PHP 5 >= 5.5.0, PHP 7) 生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低. 生成器允 ...
- ES6 Generators并发
ES6 Generators系列: ES6 Generators基本概念 深入研究ES6 Generators ES6 Generators的异步应用 ES6 Generators并发 如果你已经读过 ...
- TensorFlow中文手册
注意:本文只为读书笔记. 第一章 起步 - 起步 - [介绍](SOURCE/get_started/introduction.md) - [下载及安装](SOURCE/get_started/os_ ...
- C# 9 新特性:代码生成器、编译时反射
前言 今天 .NET 官方博客宣布 C# 9 Source Generators 第一个预览版发布,这是一个用户已经喊了快 5 年特性,今天终于发布了. 简介 Source Generators 顾名 ...
- AOP 有几种实现方式?
1. 回顾 AOP 是什么? 维基百科解释如下: 面向切面的程序设计(Aspect-oriented programming,AOP,又译作面向方面的程序设计.剖面导向程序设计)是计算机科学中的一种程 ...
- 思想无语言边界:以 cglib 介绍 AOP 在 java 的一个实现方式
0. 前言 上接:基于 Source Generators 做个 AOP 静态编织小实验 作为第三篇,我们基于cglib在java做一个简单的aop例子, 以此简单作为例子说一个思路在什么样的语言里面 ...
- 使用 C# 9 的records作为强类型ID - 初次使用
强类型ID 实体通常是整数,GUID或者string类型,因为数据库直接支持这些类型,但是,如果实体的ID的类型是一样的,比如都是整数的ID,这有可能会出现ID值传错的问题,看下边的示例. publi ...
随机推荐
- etcd实现分布式锁分析
3篇关于分布式锁的文章,可以结合看: consul实现分布式锁:https://www.cnblogs.com/jiujuan/p/10527786.html redis实现分布式锁:https:// ...
- [BUUCTF][Web][极客大挑战 2019]EasySQL 1
打开靶机对应的url 界面显示需要输入账号和密码 分别在两个输入框尝试加单引号尝试是否有sql注入的可能,比如 123' 发现两个框可以注入,因为报了个错误信息 You have an error i ...
- 使用3-hexo主题时无法正常渲染html代码
问题描述 在hexo框架中使用3-hexo主题时,会遇到这样一个问题:在markdown中嵌入html代码,这些嵌入的html代码无法正常显示. 原因分析 在使用3-hexo主题时,默认使用主题自带的 ...
- Vue框架设计:性能权衡的艺术
"框架设计里到处都体现了权衡的艺术." 当我们设计一个框架的时候,框架本身的各个模块之间并不是相互独立的,而是相互关联.相互制约的.因此作为框架设计者,一定要对框架的定位和方向拥有 ...
- context讲解
context包 context包介绍 在go语言中,每个独立调用一般都会被单独的协程处理.但在处理一个请求时,往往可能需要在多个协程之间进行信息传递,甚至包括一层层地递进顺序传递,而且这种信息往 ...
- 四: Mysql用户管理
# 用户与权限管理 MySQL用户可以分为普通用户和root用户, root用户是超级管理员,拥有所有权限,包括创建用户.删除用户和修改用户的密码等管理权限:普通用户只拥有被授予的各种权限. MySQ ...
- OBS Studio多开/多平台直播的最佳解决方案
OBS是一款强大的PC端免费的直播推流及录制工具,功能很强大,它支持开发者根据需求开发插件集成使用 我们知道OBS支持通过插件来实现多路推流,它的优点是只需开启一个OBS窗口就可以同时推流到多个不同的 ...
- 没有有线网卡的笔记本如何在PVE下All in one?—NAS + Linux +win下载机
没有有线网卡的笔记本在PVE下All in one | NAS + Linux + Win下载机 (保姆级未完成版) 目录: 1.前言 2.PVE的安装 3.PVE联网前的准备工作 4.PVE使用无线 ...
- javascript之call用法实例
call方法: 调用一个对象的一个方法,以另一个对象替换当前对象. 直接上代码: js例子:在A类中调用B类数据 function ClassA(){ this.name = 'ClassA' ...
- 29_SDL多线程与锁机制
目录 一.简介 二.代码实现: 2.1.声明 2.2.创建锁.消费者 2.3.销毁 2.4.实现生产者逻辑 2.5.实现销毁者逻辑 2.6.创建生产者 三.分装SDL锁机制 condmutex.h c ...