学习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接口。

csharp 复制代码
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,指定需要监听的文件。

xml 复制代码
<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

相关推荐
Sunsets_Red9 小时前
乘法逆元的 exgcd 求法
c++·学习·数学·算法·c#·密码学·信息学竞赛
唐青枫9 小时前
深入理解 C#.NET TaskScheduler:为什么大量使用 Work-Stealing
c#·.net
人工智能AI技术10 小时前
Claude 3.7 企业版私有化部署技术验证:与 .NET 实战方案
人工智能·c#
呆子也有梦10 小时前
思考篇:积分是存成道具还是直接存数值?——ET/Skynet 框架下,从架构权衡到代码实现全解析
游戏·架构·c#·lua
我是唐青枫10 小时前
深入理解 C#.NET Task.Run:调度原理、线程池机制与性能优化
性能优化·c#·.net
阿蒙Amon11 小时前
C#常用类库-详解NModbus4
开发语言·c#
LFly_ice11 小时前
C# Web 开发从入门到实践
开发语言·前端·c#
猹叉叉(学习版)11 小时前
【ASP.NET CORE】 14. RabbitMQ、洋葱架构
笔记·后端·架构·c#·rabbitmq·asp.net·.netcore
江沉晚呤时11 小时前
基于 AssemblyLoadContext 的 .NET 插件化架构设计与实现
开发语言·c#·.net
关关长语11 小时前
HandyControl中Button图标展示多色路径
c#·.net·wpf·handycontrol