mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
- 更新 docs/zh-CN 中 source generator 示例的命名空间到当前公开 API - 修正文档叙述与 API 参考中的旧聚合模块表述 - 对齐 source generator 家族文档与教程示例的当前模块划分
154 lines
4.8 KiB
Markdown
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)
|