Source Generator-扩充原有代码
Posted 摧残一生 涅槃重生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Source Generator-扩充原有代码相关的知识,希望对你有一定的参考价值。
我们经常会遇到,原有代码中新增方法,扩展我们自己写的代码。这个使用Source Generator也可以实现
-
在上一章的接触上新增类库(AugmentingGeneratorMethod)
-
添加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>
-
在SourceGeneratorConsole项目中添加一个类AugmentClass,添加如下代码:
namespace SourceGeneratorConsole public partial class AugmentClass public void AugmentMethod() // 调用代码生成器中的方法 this.GeneratedMethod();
调用的GeneratedMethod方法为需要代码生成器增加的,其中代码生成器需要获得命名空间和该class类才能让this生效。
-
在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);
-
在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;
-
如果想进行调试,可以使用Debugger.Launch()。
-
在SourceGeneratorConsole的Program中添加调用
//在原有的代码中进行扩展 AugmentClass augment = new AugmentClass(); augment.AugmentMethod();
-
别忘记,需要引用AugmentingGeneratorMethod项目,并添加两个属性
<ItemGroup> <ProjectReference Include="..\\SourceGeneratorXmlMethod\\SourceGeneratorXmlMethod.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup>
-
编译运行后,结果正常显示
-
总结
当生成出现错误时,大概率是未添加Generator项目的引用或者未添加OutputItemType和ReferenceOutputAssembly属性
以上是关于Source Generator-扩充原有代码的主要内容,如果未能解决你的问题,请参考以下文章
Roslyn Source Generator 未在 .net 框架 4.7.2 中生成任何源