using Microsoft.CodeAnalysis;

namespace Dpz.Core.SourceGenerator;

/// <summary>
/// 服务注册源生成器入口。
/// </summary>
/// <remarks>
/// 这个类型只负责把 Roslyn 增量生成管线接到内部实现上;服务发现、接口契约提取、
/// DI 源码生成和缓存装饰器生成分别由独立类型维护,避免入口类继续膨胀。
/// </remarks>
[Generator(LanguageNames.CSharp)]
public sealed class ServiceRegistrationGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        context.RegisterSourceOutput(
            context.CompilationProvider,
            static (sourceProductionContext, compilation) =>
            {
                var registrations = ServiceRegistrationProvider.GetRegistrations(
                    compilation,
                    sourceProductionContext
                );
                sourceProductionContext.AddSource(
                    "GeneratedServiceRegistration.g.cs",
                    ServiceRegistrationSourceBuilder.Generate(registrations)
                );

                foreach (var registration in registrations)
                {
                    sourceProductionContext.AddSource(
                        registration.CacheMetadataHintName,
                        CacheMetadataSourceGenerator.Generate(registration)
                    );

                    if (!registration.RequiresDecorator)
                    {
                        continue;
                    }

                    sourceProductionContext.AddSource(
                        registration.DecoratorHintName,
                        CacheDecoratorSourceGenerator.Generate(registration)
                    );
                }
            }
        );
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个基于 Roslyn Source Generator 的 C# 源代码生成器,用于自动生成服务注册相关的代码。

主要功能

这个 ServiceRegistrationGenerator 类实现了 IIncrementalGenerator 接口,作为源生成器的入口点,负责在编译时自动生成以下内容:

  1. 服务注册代码 - 自动生成依赖注入(DI)服务注册
  2. 缓存元数据 - 为每个服务生成缓存相关的元数据
  3. 缓存装饰器 - 根据需要为服务生成缓存装饰器模式的实现

代码结构分析

类声明

[Generator(LanguageNames.CSharp)]
public sealed class ServiceRegistrationGenerator : IIncrementalGenerator
  • [Generator] 特性标记这是一个 C# 源生成器
  • sealed 表示该类不可被继承
  • 实现 IIncrementalGenerator 接口以支持增量生成(性能更好)

Initialize 方法

这是源生成器的核心方法,设置了生成管道:

context.RegisterSourceOutput(
    context.CompilationProvider,
    static (sourceProductionContext, compilation) => { ... }
)

执行流程:

  1. 获取服务注册信息

    var registrations = ServiceRegistrationProvider.GetRegistrations(
        compilation, sourceProductionContext
    );
    

    通过 ServiceRegistrationProvider 从编译上下文中提取需要注册的服务信息

  2. 生成主注册文件

    sourceProductionContext.AddSource(
        "GeneratedServiceRegistration.g.cs",
        ServiceRegistrationSourceBuilder.Generate(registrations)
    );
    

    生成一个包含所有服务注册代码的文件

  3. 为每个服务生成附加文件

    foreach (var registration in registrations)
    {
        // 生成缓存元数据
        sourceProductionContext.AddSource(
            registration.CacheMetadataHintName,
            CacheMetadataSourceGenerator.Generate(registration)
        );
    
        // 如果需要装饰器,生成装饰器代码
        if (registration.RequiresDecorator)
        {
            sourceProductionContext.AddSource(
                registration.DecoratorHintName,
                CacheDecoratorSourceGenerator.Generate(registration)
            );
        }
    }
    

设计优势

根据注释说明,这个设计遵循了单一职责原则

  • ServiceRegistrationGenerator:仅负责连接 Roslyn 管道
  • ServiceRegistrationProvider:负责服务发现和接口契约提取
  • ServiceRegistrationSourceBuilder:负责生成 DI 注册代码
  • CacheMetadataSourceGenerator:负责生成缓存元数据
  • CacheDecoratorSourceGenerator:负责生成缓存装饰器

这种分离避免了入口类过度膨胀,提高了代码的可维护性和可测试性。

评论加载中...