当前位置: 首页 > news >正文

C# IIncrementalGenerator干点啥

生成器项目

得基于.Net Stander 2.0
重要:<IsRoslynComponent>true</IsRoslynComponent>、<IncludeBuildOutput>false</IncludeBuildOutput>、    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.14.0" />

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><IncludeBuildOutput>false</IncludeBuildOutput><LangVersion>latest</LangVersion><IsRoslynComponent>true</IsRoslynComponent></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.CodeAnalysis" Version="4.14.0" /></ItemGroup><ItemGroup><PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.14.0" PrivateAssets="all" /></ItemGroup><ItemGroup><ProjectReference Include="..\..\MasterNeverDown.SA\MasterNeverDown.SA.csproj" /></ItemGroup>
</Project>

生成器示例

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Text;namespace LoggingGenerator
{[Generator]public class LoggingGenerator : IIncrementalGenerator{// 记录初始化过程public LoggingGenerator(){System.Diagnostics.Debug.WriteLine("LoggingGenerator initialized");}public void Initialize(IncrementalGeneratorInitializationContext context){//Debugger.Launch();// 记录初始化开始LogMessage("Initializing generator");// 筛选出标记了[LogMethod]特性的方法IncrementalValuesProvider<IMethodSymbol> methodsToLog = context.SyntaxProvider.CreateSyntaxProvider(predicate: (s, _) => IsMethodDeclarationWithAttribute(s),transform: (ctx, _) => GetMethodSymbol(ctx)).Where(m => m != null)!;// 注册代码生成操作context.RegisterSourceOutput(methodsToLog.Collect(),(spc, methods) => GenerateLoggingCode(spc, methods));// 记录初始化完成LogMessage("Generator initialization completed");}private bool IsMethodDeclarationWithAttribute(SyntaxNode node){// 检查是否为方法声明且有LogMethod特性if (node is not Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax methodSyntax)return false;return methodSyntax.AttributeLists.Any(al =>al.Attributes.Any(a => a.Name.ToString() == "LogMethod"));}private IMethodSymbol? GetMethodSymbol(GeneratorSyntaxContext context){var methodSyntax = (Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax)context.Node;return context.SemanticModel.GetDeclaredSymbol(methodSyntax) as IMethodSymbol;}private void GenerateLoggingCode(SourceProductionContext context, ImmutableArray<IMethodSymbol> methods){// 记录代码生成开始LogMessage($"Starting code generation for {methods.Length} methods");foreach (var method in methods){try{// 生成方法日志代码var source = GenerateMethodLogging(method);var hintName = $"{method.ContainingType.Name}_{method.Name}.g.cs";context.AddSource(hintName, SourceText.From(source, Encoding.UTF8));// 记录成功生成LogMessage($"Generated logging code for {method.ContainingType.Name}.{method.Name}");}catch (Exception ex){// 记录生成失败LogError($"Failed to generate code for {method.ContainingType.Name}.{method.Name}: {ex.Message}");}}// 记录代码生成完成LogMessage("Code generation completed");}private string GenerateMethodLogging(IMethodSymbol method){// 构建方法日志代码var className = method.ContainingType.Name;var methodName = method.Name;var parameters = string.Join(", ", method.Parameters.Select(p => $"{p.Type} {p.Name}"));var builder = new StringBuilder();builder.AppendLine("// <auto-generated>");builder.AppendLine("// This code was generated by a source generator.");builder.AppendLine("// </auto-generated>");builder.AppendLine();builder.AppendLine($"namespace {method.ContainingNamespace.ToDisplayString()}");builder.AppendLine("{");builder.AppendLine($"    public partial class {className}");builder.AppendLine("    {");builder.AppendLine($"        partial void On{methodName}Executing({parameters});");builder.AppendLine($"        partial void On{methodName}Executing({parameters})");builder.AppendLine("        {");builder.AppendLine($"            System.Diagnostics.Debug.WriteLine(\"Entering method {methodName}\");");// 记录参数foreach (var param in method.Parameters){builder.AppendLine($"            System.Diagnostics.Debug.WriteLine(\"  Parameter {param.Name}: \" + ({param.Name}?.ToString() ?? \"null\"));");}builder.AppendLine("        }");builder.AppendLine();builder.AppendLine($"        partial void On{methodName}Executed({parameters});");builder.AppendLine($"        partial void On{methodName}Executed({parameters})");builder.AppendLine("        {");builder.AppendLine($"            System.Diagnostics.Debug.WriteLine(\"Exiting method {methodName}\");");builder.AppendLine("        }");builder.AppendLine("    }");builder.AppendLine("}");return builder.ToString();}// 日志方法 - 可根据需要调整输出方式private void LogMessage(string message){System.Diagnostics.Debug.WriteLine($"[LoggingGenerator] {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}");}private void LogError(string message){System.Diagnostics.Debug.WriteLine($"[LoggingGenerator ERROR] {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}");}}
}

项目代码

重要: OutputItemType="Analyzer" ReferenceOutputAssembly="false"

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net8.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.CodeAnalysis" Version="4.14.0" /></ItemGroup><ItemGroup><ProjectReference Include="..\MasterNeverDown.SA\MasterNeverDown.SA.csproj" /><ProjectReference Include="..\Sd\Sd\Sd.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /></ItemGroup><ItemGroup><Compilervisibility Include="PublicApiAnalyzer" Version="1.0.0" /></ItemGroup>
</Project>

结果

在依赖项=》分析器=》项目生成g.cs,注意变更源生成器需要重新打开工程来刷新新生成的代码

http://www.lryc.cn/news/582786.html

相关文章:

  • N8N与Dify:自动化与AI的完美搭配
  • 基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(1)搭建框架基本雏形
  • UE5内置插件 AnimToTexture 简单入门
  • Spring Boot 项目中的多数据源配置
  • ElasticSearch集群状态查询及_cat 命令详解
  • GitHub Copilot 三种模式详解:Ask、Agent、Edit
  • 【web安全】SQLMap 参数深度解析:--risk 与 --level 详解
  • leetcode-二叉树的层序遍历-113
  • 基于Java+Maven+Testng+RestAssured+Allure+Jenkins搭建一个接口自动化框架
  • 谁主沉浮:人工智能对未来信息技术发展路径的影响研究
  • 基于 Rust 的Actix Web 框架的应用与优化实例
  • 从零构建MCP服务器:FastMCP实战指南
  • 基于物联网架构的温室环境温湿度传感器节点设计
  • 微信小程序控制空调之接收MQTT消息
  • Maven 打包排除特定依赖的完整指南(详细方法 + 示例)
  • 作业03-SparkSQL开发
  • 无缝矩阵的音频合成与音频分离功能详解
  • Rust BSS段原理与实践解析
  • RustFS一款Rust 驱动的 高性能 分布式存储系统
  • Modbus TCP转Profinet网关实现视觉相机与西门子PLC配置实例研究
  • Tomcat:启用https(Windows)
  • 传输层协议TCP、UDP
  • CI/CD — DevOps概念之实现k8s持续交付持续集成(一)
  • 数据结构:位图
  • IDEA Maven报错 无法解析 com.taobao:parent:pom:1.0.1【100%解决 此类型问题】
  • 分布式光纤传感:为储能安全保驾护航
  • 广度优先与深度优先遍历核心逻辑理解及实践
  • 关于 scrapy框架 详解
  • OpenCV在Visual Studio 2022下的配置
  • Android 中的多线程编程全面解析