You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在单个项目中实现C#源代码生成器的组合使用?

单个项目中组合使用C#源代码生成器的可行性

可以在单个项目中实现多轮源代码生成,让后续生成器基于前序生成器的输出代码工作,无需拆分项目。核心是利用编译器的增量生成机制和生成器执行顺序控制,具体实现要点如下:

  • 控制生成器执行顺序
    默认编译器会并行执行所有生成器,要让SecondSourceGenerator依赖FirstSourceGenerator的输出,需通过[Generator]特性的ExecutionOrder参数指定执行优先级:

    [Generator(ExecutionOrder = -1)] // 数值越小越先执行
    public class FirstSourceGenerator : IIncrementalGenerator
    {
        // 生成逻辑
    }
    
    [Generator(ExecutionOrder = 0)]
    public class SecondSourceGenerator : IIncrementalGenerator
    {
        // 基于FirstSourceGenerator的输出生成代码
    }
    
  • 开启多轮生成与符号分析
    在项目文件(.csproj)中添加配置,让编译器在每轮生成后处理符号并触发后续生成:

    <PropertyGroup>
      <!-- 启用增量生成模式 -->
      <EnableIncrementalGeneratorExecution>true</EnableIncrementalGeneratorExecution>
      <GeneratorExecutionMode>Incremental</GeneratorExecutionMode>
      <!-- 可选:输出生成的代码以便调试 -->
      <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
    </PropertyGroup>
    
  • 基于符号操作生成代码
    在SecondSourceGenerator中,通过增量生成的SyntaxProvider匹配前序生成的代码节点,再通过编译上下文获取已验证的符号:

    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        // 匹配FirstSourceGenerator生成的带有特定标记的类
        var generatedClasses = context.SyntaxProvider.CreateSyntaxProvider(
            predicate: (node, _) => node is ClassDeclarationSyntax cls && cls.AttributeLists.Any(
                al => al.Attributes.Any(a => a.Name.ToString() == "GeneratedByFirstGenerator")),
            transform: (ctx, _) => ctx.SemanticModel.GetDeclaredSymbol(ctx.Node as ClassDeclarationSyntax)
        );
    
        // 基于获取到的符号生成新代码
        context.RegisterSourceOutput(generatedClasses, (spc, symbol) =>
        {
            // 使用symbol的属性、方法等信息生成代码
            spc.AddSource($"{symbol.Name}_Generated.cs", $"public static class {symbol.Name}Extensions {{ /* 生成代码 */ }}");
        });
    }
    
  • 关键注意事项

    • 给前序生成的代码添加唯一标识(如自定义属性),方便后续生成器精准匹配。
    • 实现正确的增量缓存逻辑,避免重复生成,提升编译效率。
    • 开启EmitCompilerGeneratedFiles后,可在项目的obj/Debug/netX/GeneratedFiles目录下查看每轮生成的代码,验证流程是否符合预期。

这种单项目方案既保留了拆分项目时的优势——能操作编译器验证后的符号、每轮生成后自动做语法检查,又无需维护多个项目结构。

内容的提问来源于stack exchange,提问作者user1576055

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:07:45