Files

4.7 KiB
Raw Permalink Blame History

AtomUI 源生成器(Source Generator)设计原理

本文档详细介绍 AtomUI 的两个 Roslyn 源生成器的设计原理与内部实现,重点聚焦于 Token 系统和多语言系统的底层代码生成机制。
适用版本:AtomUI v5.0+,基于 Avalonia v11
最后更新:2026-04-11


文档索引

文档 内容
TokenResourceKeyGenerator 设计原理 Token 资源键生成器:扫描 [GlobalDesignToken] 和 [ControlDesignToken],自动生成 SharedTokenKind 枚举、XxxTokenKind 枚举、XAML 标记扩展类、ControlTokenTypePool 类型注册池
LanguageGenerator 设计原理 多语言资源生成器:扫描 [LanguageProvider],自动生成 XxxLangResourceKind 枚举、XAML 标记扩展类、LanguageProviderPool 实例注册池

为什么需要源生成器

AtomUI 的 Token 系统和多语言系统需要在 C# 定义 和 AXAML 消费 之间建立类型安全的桥接。核心问题是:

  1. Token 属性 定义在 C# 类中(如 TagToken.DefaultBg),但需要在 AXAML 中通过标记扩展引用(如 {atom:TagTokenResource DefaultBg})。
  2. 语言文本 定义在 C# 类中(如 en_US.Uploading),但需要在 AXAML 中通过标记扩展引用(如 {atom:UploadLangResource Uploading})。
  3. ThemeManager 需要在运行时发现所有 Token 类型和 LanguageProvider 实例,以便完成 Token 注册和语言资源加载。

如果手写这些桥接代码,开发者每新增一个 Token 属性或语言字段,都需要手动同步更新枚举、标记扩展类和注册池——极易遗漏且高度重复。

源生成器通过 编译时自动分析 C# 源码,一次性生成所有桥接代码,实现 单一事实来源(Single Source of Truth):

开发者编写                          源生成器自动生成                    AXAML/运行时消费
─────────────                      ──────────────────                  ────────────────
[ControlDesignToken]               TagTokenKind 枚举                  {atom:TagTokenResource DefaultBg}
class TagToken                ───► TagTokenResourceExtension 类   ──►
  DefaultBg { get; set; }          ControlTokenTypePool 注册          ThemeManager.RegisterControlTokenType()

[LanguageProvider]                 UploadLangResourceKind 枚举        {atom:UploadLangResource Uploading}
class en_US                   ───► UploadLangResourceExtension 类 ──►
  Uploading = "..."                LanguageProviderPool 注册          ThemeManager 加载语言资源

源生成器项目概览

项目信息

属性 值
项目 src/AtomUI.Generator/AtomUI.Generator.csproj
目标框架 netstandard2.0(Roslyn Source Generator 强制要求)
消费方式 作为 Analyzer 引用,不产出运行时 DLL
依赖 仅 Microsoft.CodeAnalysis.CSharp 和 Microsoft.CodeAnalysis.Analyzers

两个生成器

生成器类 标记注解 生成产物
TokenResourceKeyGenerator [GlobalDesignToken] / [ControlDesignToken] TokenResourceConst.g.cs / ControlTokenTypePool.g.cs
LanguageGenerator [LanguageProvider] LanguageResourceConst.g.cs / LanguageProviderPool.g.cs

生成文件位置

生成的文件输出到各项目的 GeneratedFiles/AtomUI.Generator/ 目录下:

src/AtomUI.Desktop.Controls/
└── GeneratedFiles/
    └── AtomUI.Generator/
        ├── AtomUI.Generator.TokenResourceKeyGenerator/
        │   ├── TokenResourceConst.g.cs         # Token 枚举 + 标记扩展
        │   └── ControlTokenTypePool.g.cs       # Token 类型注册池
        └── AtomUI.Generator.LanguageGenerator/
            ├── LanguageResourceConst.g.cs       # 语言枚举 + 标记扩展
            └── LanguageProviderPool.g.cs        # 语言提供者注册池

重要:这些文件由编译器自动生成,禁止手动编辑。项目通过 <Compile Remove="GeneratedFiles/**"> 排除这些文件的直接编译(由源生成器注入)。


核心设计模式

两个生成器遵循相同的架构模式:

1. 标记注解(Attribute)    →  标识目标类
2. 语法树遍历器(Walker)   →  提取元数据(属性名、字段名、命名空间等)
3. 源码写入器(Writer)     →  通过 Roslyn SyntaxFactory 构建并输出 C# 代码

这种 Attribute → Walker → Writer 三段式管线是 AtomUI 源生成器的统一架构。详细原理请参阅各生成器的独立文档。