GFramework/docs/zh-CN/source-generators/auto-register-module-generator.md
gewuyou 4eca2f1060 docs(cqrs): 收口 source generator 文档命名空间
- 更新 docs/zh-CN 中 source generator 示例的命名空间到当前公开 API
- 修正文档叙述与 API 参考中的旧聚合模块表述
- 对齐 source generator 家族文档与教程示例的当前模块划分
2026-04-18 23:30:33 +08:00

154 lines
4.8 KiB
Markdown

# AutoRegisterModule 生成器
> 为架构模块生成固定顺序的组件注册代码,收敛 `Install(IArchitecture)` 样板。
## 概述
`AutoRegisterModule` 面向 GFramework 的模块安装场景。
当一个模块类只需要按固定顺序注册若干 `Model``System``Utility` 时,开发者不必再手写重复的 `Install(IArchitecture)` 方法。
生成器会扫描类上的:
- `[AutoRegisterModule]`
- `[RegisterModel(typeof(...))]`
- `[RegisterSystem(typeof(...))]`
- `[RegisterUtility(typeof(...))]`
然后在编译期生成统一的安装方法。
### 核心收益
- 把模块注册入口收敛到声明式 Attribute
- 避免漏注册、顺序漂移和重复样板
- 保持零运行时反射开销
## 基础使用
```csharp
using GFramework.Core.Abstractions.Architectures;
using GFramework.Core.Abstractions.Model;
using GFramework.Core.Abstractions.Systems;
using GFramework.Core.Abstractions.Utility;
using GFramework.Core.SourceGenerators.Abstractions.Architectures;
public sealed class RunStateModel : IModel
{
}
public sealed class BuildSystem : ISystem
{
}
public sealed class GridPathUtility : IUtility
{
}
[AutoRegisterModule]
[RegisterModel(typeof(RunStateModel))]
[RegisterSystem(typeof(BuildSystem))]
[RegisterUtility(typeof(GridPathUtility))]
public partial class GameplayModule
{
}
```
## 生成的代码
编译器会生成与下述结构等价的代码:
```csharp
// <auto-generated />
#nullable enable
partial class GameplayModule
{
public void Install(global::GFramework.Core.Abstractions.Architectures.IArchitecture architecture)
{
architecture.RegisterModel(new global::RunStateModel());
architecture.RegisterSystem(new global::BuildSystem());
architecture.RegisterUtility(new global::GridPathUtility());
}
}
```
## 参数说明
### `[AutoRegisterModule]`
类级标记,用于声明该类型允许生成 `Install(IArchitecture)`
### `[RegisterModel(typeof(TModel))]`
| 参数 | 类型 | 说明 |
|-------------|--------|--------------------|
| `modelType` | `Type` | 要注册的 `IModel` 实现类型 |
### `[RegisterSystem(typeof(TSystem))]`
| 参数 | 类型 | 说明 |
|--------------|--------|---------------------|
| `systemType` | `Type` | 要注册的 `ISystem` 实现类型 |
### `[RegisterUtility(typeof(TUtility))]`
| 参数 | 类型 | 说明 |
|---------------|--------|----------------------|
| `utilityType` | `Type` | 要注册的 `IUtility` 实现类型 |
## 顺序规则
生成器会按 Attribute 的稳定声明顺序输出注册语句。
- 同一个 `partial` 声明内:按源码书写顺序生成
- 多个 `partial` 文件之间:按语法树稳定顺序合并
这意味着模块安装顺序是可预期的,适合游戏启动时需要确定初始化顺序的场景。
## 适用场景
推荐用于:
- 游戏主架构中的固定模块安装
- 菜单模块、战斗模块、局内模块等声明式注册
- 仅依赖无参构造即可完成初始化的组件
不推荐用于:
- 需要运行时参数、配置对象或工厂参与构造的组件
- 注册前必须执行复杂前置逻辑的模块
- 注册逻辑本身存在分支、条件或环境判断的模块
## 使用约束
- 目标类型必须是 `partial class`
- 不支持嵌套类
- 目标类型上不能自己再声明 `Install(IArchitecture)`
- 注册类型必须是具体类型,不能是抽象类或接口
- 注册类型必须实现对应接口:
- `RegisterModel` 对应 `IModel`
- `RegisterSystem` 对应 `ISystem`
- `RegisterUtility` 对应 `IUtility`
- 注册类型必须存在可访问的无参构造函数
## 诊断信息
| 诊断 ID | 含义 |
|-----------------------|------------------------------------------|
| `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 |
| `GF_AutoModule_001` | `AutoRegisterModule` 不支持嵌套类 |
| `GF_AutoModule_002` | 注册特性没有提供有效的具体类型参数 |
| `GF_AutoModule_003` | 注册类型没有实现要求的接口 |
| `GF_AutoModule_004` | 注册类型缺少可访问的无参构造 |
| `GF_AutoModule_005` | 宿主类型已声明 `Install(IArchitecture)`,与生成代码冲突 |
## 注意事项
- 生成器只负责生成安装方法,不会自动调用它;模块仍需由你的架构启动逻辑显式执行。
- 如果某个组件需要通过 Service、配置表或 Godot 导出字段来完成构造,优先保留手写注册代码。
- 当注册逻辑已经包含较强的业务语义时,不要为了消灭几行代码而强行改成声明式生成。
## 相关文档
- [源码生成器总览](./index)
- [Context Get 注入生成器](./context-get-generator)