首页 > 其他分享 >Source Generator-扩充原有代码

Source Generator-扩充原有代码

时间:2023-03-20 17:12:11浏览次数:45  
标签:Generator class Microsoft Source CodeAnalysis 添加 using 扩充 public

我们经常会遇到,原有代码中新增方法,扩展我们自己写的代码。这个使用Source Generator也可以实现

  1. 在上一章的接触上新增类库(AugmentingGeneratorMethod)

  2. 添加Microsoft.CodeAnalysis.Analyzers 和 Microsoft.CodeAnalysis.CSharp引用:

      <ItemGroup>
        <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" PrivateAssets="all" />
        <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
      </ItemGroup>
    
  3. 在SourceGeneratorConsole项目中添加一个类AugmentClass,添加如下代码:

    namespace SourceGeneratorConsole
    {
        public partial class AugmentClass
        {
            public void AugmentMethod()
            {
                // 调用代码生成器中的方法
                this.GeneratedMethod();
            }
        }
    }
    

    调用的GeneratedMethod方法为需要代码生成器增加的,其中代码生成器需要获得命名空间和该class类才能让this生效。

  4. 在AugmentingGeneratorMethod中新建一个cs文件,命名为AugmentingGenerator。添加如下代码

    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.CSharp.Syntax;
    using Microsoft.CodeAnalysis.Text;
    using System;
    using System.Diagnostics;
    using System.Text;
    
    namespace AugmentingGeneratorMethod
    {
        [Generator]
        public class AugmentingGenerator : ISourceGenerator
        {
            public void Initialize(GeneratorInitializationContext context)
            {
                // 自定义一个语法接收器的工厂,然后通过该工厂向已有的class类中添加新方法
                context.RegisterForSyntaxNotifications(() => new AugmentSyntaxReceiver());
            }
    
            public void Execute(GeneratorExecutionContext context)
            {
                // 获得创建的语法接收器,然后通过context进行操作
                AugmentSyntaxReceiver syntaxReceiver = (AugmentSyntaxReceiver)context.SyntaxReceiver;
    
                // 通过语法接收器获得class类
                ClassDeclarationSyntax augmentClass = syntaxReceiver.ClassToAugment;
                //判断是否有这个类
                if (augmentClass is null)
                {
                    //没有找到就不做任何事情
                    return;
                }
    
                //找到了就添加一个方法
                SourceText sourceText = SourceText.From($@"
                    namespace {syntaxReceiver.SpaceToAugment.Name.GetText()}
                    {{
                        public partial class {augmentClass.Identifier}
                        {{
                            private void GeneratedMethod()
                            {{
                                Console.WriteLine(""Hello, augmentClass!"");
                            }}
                        }}
                    }}", Encoding.UTF8);
                context.AddSource("augmentClass.Generated.cs", sourceText);
            }
        }
    }
    
  5. 在AugmentingGeneratorMethod项目中添加语法接收器(AugmentSyntaxReceiver),代码如下

    using Microsoft.CodeAnalysis.CSharp.Syntax;
    using Microsoft.CodeAnalysis;
    
    namespace AugmentingGeneratorMethod
    {
        class AugmentSyntaxReceiver : ISyntaxReceiver
        {
            // 获得类名
            public ClassDeclarationSyntax ClassToAugment { get; private set; }
            // 获得命名空间
            public NamespaceDeclarationSyntax SpaceToAugment { get; private set; }
    
            public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
            {
                //Debugger.Launch();
                if (syntaxNode is NamespaceDeclarationSyntax csd) {
                    SpaceToAugment = csd;
                }
                // 判断是否有AugmentClass,如果有则赋值
                if (syntaxNode is ClassDeclarationSyntax cds &&
                    cds.Identifier.ValueText == "AugmentClass")
                {
                    
                    ClassToAugment = cds;
                }
            }
        }
    }
    
  6. 如果想进行调试,可以使用Debugger.Launch()。

  7. 在SourceGeneratorConsole的Program中添加调用

    //在原有的代码中进行扩展
    AugmentClass augment = new AugmentClass();
    augment.AugmentMethod();
    
  8. 别忘记,需要引用AugmentingGeneratorMethod项目,并添加两个属性

      <ItemGroup>
        <ProjectReference Include="..\SourceGeneratorXmlMethod\SourceGeneratorXmlMethod.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
      </ItemGroup>
    
  9. 编译运行后,结果正常显示

  10. 总结

    当生成出现错误时,大概率是未添加Generator项目的引用或者未添加OutputItemType和ReferenceOutputAssembly属性

标签:Generator,class,Microsoft,Source,CodeAnalysis,添加,using,扩充,public
From: https://www.cnblogs.com/wanghun315/p/17236982.html

相关文章

  • Source Generator-编译本地文件的中的代码
    上一篇讲解了如何直接调用静态方法,而有时候我们会生成cs文件或其他格式的文件,进而使用SourceGenerator编译。本例中就对资源文件进行编译进行举例说明。在SourceGener......
  • resources目录下的mapper写sql语句没有提示
    resources目录下的mapper写sql语句没有提示首先了解一下mybatix-config.xml连接mapper文件的三种方式:<!--第一种--><mapperresource="com/bbl/dao/UserMa......
  • Source Insight 4.0使用介绍
    简介SourceInsight是一个功能非常强大的,面向项目的程序编辑器,具有针对C/C++,C#,Java,Objective-C等的内置动态分析。SourceInsight可实现多文件代码中变量和函数的快......
  • Vue插件:Vue-resource github搜索示例
     1:安装插件  vue-resourcevue的插件库,在vue1.0年代使用几率很高......
  • 【spring框架】关于DataSource(下)
    spring连接池的配置,可以有三种连接池的配置(常用):i.c3p0ii.dbcpiii.proxool用到哪种去查那种情况的配置即可。下面我们主要说dbcp。除了......
  • use GitHub Actions auto generator markdown file
    useGitHubActionsautogeneratormarkdownfile✅GitHubIssuesTemplate+GitHubActionsCI/CDdemosCrawlpagesandgenerateMarkdownfilesfreeCodeCamp......
  • DataSource,DriverManger,Driver和JdbcTemplate
    JDBC1.0使用DriverManager类来产生一个对数据源的连接,相对于DriverManager,JDBC2.0提供的DataSource接口是一个更好的连接数据源的方法。DataSource相比于前者无需硬性编码......
  • 干货 | BitSail Connector 开发详解系列一:Source
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 BitSail是字节跳动自研的数据集成产品,支持多种异构数据源间的数据同步,并提供离......
  • Java 使用 ResourceBundle 类读取 properties 文件中文乱码的解决方案
    Java使用ResourceBundle类读取properties文件中文乱码的解决方案https://www.cnblogs.com/poterliu/p/10159577.htmlJava使用java.util.ResourceBundle类的方式来......
  • 显卡知识扩充
    一、关键字OC(一键OC核心频率)超频版。在出厂前,厂家进行过预超频,默认频率高于普通版,寿命比普通版久。FG、LHR、L锁算力版。限制挖矿的显卡版本,NVIDIA通过限制哈希算法的......