Files
AtomUI/docs/Generator/Overview.md
T

94 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AtomUI 源生成器(Source Generator)设计原理
> 本文档详细介绍 AtomUI 的两个 Roslyn 源生成器的设计原理与内部实现,重点聚焦于 Token 系统和多语言系统的底层代码生成机制。
> 适用版本:AtomUI v5.0+,基于 Avalonia v11
> 最后更新:2026-04-11
---
## 文档索引
| 文档 | 内容 |
|---|---|
| [TokenResourceKeyGenerator 设计原理](./TokenResourceKeyGenerator.md) | Token 资源键生成器:扫描 `[GlobalDesignToken]` 和 `[ControlDesignToken]`,自动生成 `SharedTokenKind` 枚举、`XxxTokenKind` 枚举、XAML 标记扩展类、`ControlTokenTypePool` 类型注册池 |
| [LanguageGenerator 设计原理](./LanguageGenerator.md) | 多语言资源生成器:扫描 `[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 源生成器的统一架构。详细原理请参阅各生成器的独立文档。