前面我们使用了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的更多相关文章

  1. 基于 Source Generators 做个 AOP 静态编织小实验

    0. 前言 上接:用 Roslyn 做个 JIT 的 AOP 作为第二篇,我们基于Source Generators做个AOP静态编织小实验. 内容安排如下: source generators 是什 ...

  2. .NET初探源代码生成(Source Generators)

    前言 Source Generators顾名思义代码生成器,可进行创建编译时代码,也就是所谓的编译时元编程,这可让一些运行时映射的代码改为编译时,同样也加快了速度,我们可避免那种昂贵的开销,这是有价值 ...

  3. 使用 MVVM Toolkit Source Generators

    关于 MVVM Toolkit 最近 .NET Community Toolkit 发布了 8.0.0 preview1,它包含了从 Windows Community Toolkit 迁移过来的以下 ...

  4. PHP的学习--生成器Generators

    生成器总览 (PHP 5 >= 5.5.0, PHP 7) 生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低. 生成器允 ...

  5. ES6 Generators并发

    ES6 Generators系列: ES6 Generators基本概念 深入研究ES6 Generators ES6 Generators的异步应用 ES6 Generators并发 如果你已经读过 ...

  6. TensorFlow中文手册

    注意:本文只为读书笔记. 第一章 起步 - 起步 - [介绍](SOURCE/get_started/introduction.md) - [下载及安装](SOURCE/get_started/os_ ...

  7. C# 9 新特性:代码生成器、编译时反射

    前言 今天 .NET 官方博客宣布 C# 9 Source Generators 第一个预览版发布,这是一个用户已经喊了快 5 年特性,今天终于发布了. 简介 Source Generators 顾名 ...

  8. AOP 有几种实现方式?

    1. 回顾 AOP 是什么? 维基百科解释如下: 面向切面的程序设计(Aspect-oriented programming,AOP,又译作面向方面的程序设计.剖面导向程序设计)是计算机科学中的一种程 ...

  9. 思想无语言边界:以 cglib 介绍 AOP 在 java 的一个实现方式

    0. 前言 上接:基于 Source Generators 做个 AOP 静态编织小实验 作为第三篇,我们基于cglib在java做一个简单的aop例子, 以此简单作为例子说一个思路在什么样的语言里面 ...

  10. 使用 C# 9 的records作为强类型ID - 初次使用

    强类型ID 实体通常是整数,GUID或者string类型,因为数据库直接支持这些类型,但是,如果实体的ID的类型是一样的,比如都是整数的ID,这有可能会出现ID值传错的问题,看下边的示例. publi ...

随机推荐

  1. Golang gRPC学习(05): retry重试

    什么是重试 如果服务出现了错误,主要是网络,服务器出现了短暂异常的时候,该怎么办? 我们都会人工或者自动的重新连接服务试试,看服务是否恢复可用了. 这种重新进行连接服务的一种方式就是重试.如果是在微服 ...

  2. geacon_pro配合catcs4.5上线Mac、Linux

    最新最全文章见我个人博客: xzajyjs.cn 一些链接 Try师傅的catcs4.5项目: https://github.com/TryGOTry/CobaltStrike_Cat_4.5,最新版 ...

  3. 商店销售预测(回归&随机森林)

    ​ 目录 一.题目概要 二.导入包和数据集 三.数据处理 四.描述性分析 五.探索性数据分析 六.模型一:线性回归 七.模型2:随机森林 一.题目概要 在Kaggle竞赛中,要求我们应用时间序列预测, ...

  4. Kotlin 协程二 —— 通道 Channel

    目录 一. Channel 基本使用 1.1 Channel 的概念 1.2 Channel 的简单使用 1.3 Channel 的迭代 1.4 close 关闭 Channel 1.5 Channe ...

  5. 【Azure 应用服务】App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢?

    问题描述 App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢? 问题解答 答案是可以的,Azure App Service .NE ...

  6. Java 封装+构造器+this 小测试

    1 package com.bytezero.account; 2 3 4 public class Account 5 { 6 private int id; //账号 7 private doub ...

  7. 【容斥、插值】P3270 [JLOI2016]成绩比较

    [容斥.插值]P3270 [JLOI2016]成绩比较 题目简述 有 \(n+1\) 个人,进行 \(m\) 场考试,第 \(i\) 场考试的可能得分是 \([0,U_i]\) 之间的整数. 假设你是 ...

  8. C++左值右值完美转发转移

    左值(Lvalue)与右值(Rvalue) 英文含义: 左值(Lvalue):Locator value,意味着它指向一个具体的内存位置. 右值(Rvalue):Read value,指的是可以读取的 ...

  9. nowrap - table td 列 宽度 不被挤 - 大表格制作

    nowrap - table td 列 宽度 不被挤 - 大表格制作 表格前几列 设置完宽度,会被右侧动态数据挤没有宽度,加上nowrap,就保证宽度了

  10. end_of_line = lf 选择行尾序列 .editorconfig - 老项目不动代码存盘 文件变动 CRLF 的问题 vscode

    end_of_line = lf 选择行尾序列 .editorconfig - 老项目不动代码存盘 文件变动 CRLF 的问题 缘由 vscode 老项目代码,没有变动,ctrl + s后 文件有变化 ...