• 学习Source Generators之IncrementalValueProvider


    前面我们使用了IIncrementalGenerator来生成代码,接下来我们来详细了解下IIncrementalGenerator的核心部分IncrementalValueProvider。

    介绍#

    IncrementalValueProvider是基于管道的模式,将我们需要的数据进行处理转换后传递给SourceOutput。
    目前官方提供可用的Providers有如下几种:

    • CompilationProvider
    • AdditionalTextsProvider
    • AnalyzerConfigOptionsProvider
    • MetadataReferencesProvider
    • ParseOptionsProvider

    实操#

    接下来我们来使用AdditionalTextsProvider来学习IncrementalValueProvider的运行方式。

    创建项目#

    首先创建LearnIncrementalValueProvider的控制台程序和LearnIncrementalValueProvider.Analysis的netstandard2.0类库两个项目。
    image.png
    按照前面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的委托中。
    image.png
    这是因为AdditionalTextsProvider并没有找到任何需要加载的文件。
    我们需要在控制台程序的项目文件中添加AdditionalFiles,指定需要监听的文件。

    <ItemGroup>
      <AdditionalFiles Include="Files/*" />
    ItemGroup>
    

    添加AdditionalFiles后,在调试一次。
    image.png
    可以看到断点成功进来了。并且可以看到获取的文件路径以及文件的文本内容。
    image.png

    多个文件#

    在Files目录中添加一个txt文件。并写入文本HelloWorld
    image.png
    然后再调试一次。可以发现,每一个文件都会单独执行一次委托的方法。
    image.png

    过滤文件#

    当我们只需要其中一种类型的文件的时候,我们可以通过Where来进行过滤筛选。
    image.png
    通过Debugger.Log可以发现,只输出了json的文件路径。
    image.png

    处理数据#

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

    集合#

    如果不想多次处理文件的话,可以使用Collect方法,直接把多个文件合并在一起。
    image.png
    这里可以看到,使用Collect,2个文件可以同时处理。

    组合多个IncrementalValueProvider#

    除了对单个IncrementalValueProvider进行处理外,我们还可以组合不同的IncrementalValueProvider。
    比如将CompilationProvider和AdditionalTextsProvider组合起来。
    使用Combine方法。
    image.png
    可以看到 paris的Right和Left分别是CompilationProvider和AdditionalTextsProvider两种类型。

    结语#

    以上就是IncrementalValueProvider比较常用的方式。通过这些操作可以灵活的实现我们的代码生成逻辑。
    当然还有其他的IncrementalValueProvider,这里就不都写出来了。其他的可以自己实操玩起来~
    本文代码仓库地址https://github.com/fanslead/Learn-SourceGenerator

  • 相关阅读:
    IDE的组成
    啃完这本阿里手册,应届七面进阿里
    解锁OpenAI潜力:OpenAI 全面解析与最佳实践
    Qt实现sdp组包,sdp策略介绍
    HIVE优化和数据倾斜、合并小文件
    Python3虚拟环境之pipenv
    从 QFramework 重新开始
    web3D三维引擎(Direct3D、OpenGL、UE、U3D、threejs)基础扫盲
    MTR 网络连通性测试工具 基础入门 整理
    ArcGIS中ArcMap栅格图层0值设置为NoData值的简便方法
  • 原文地址:https://www.cnblogs.com/fanshaoO/p/18108051