# AutoRegisterExportedCollections 生成器 > 为 Godot 导出集合生成批量注册方法,收敛启动入口里的重复 `foreach + Registry(...)` 样板。 ## 概述 在游戏启动入口中,常见的一类样板是: - 在 Inspector 中导出一批配置、资源映射或预制体条目 - 从某个 Registry 成员拿到注册器 - 遍历集合逐项调用 `Register(...)` / `Registry(...)` `AutoRegisterExportedCollections` 会把这类样板收敛成声明式配置。 它特别适合 `GameEntryPoint`、资源根节点、配置引导节点这类“导出即注册”的场景。 ## 基础使用 ```csharp using System.Collections.Generic; using GFramework.Godot.SourceGenerators.Abstractions; using Godot; public interface IKeyValue { } public interface IRegistry { void Registry(IKeyValue mapping); } public interface IAssetRegistry : IRegistry { } public sealed class TextureConfig : Resource, IKeyValue { } public sealed class TextureRegistry : IAssetRegistry { public void Registry(IKeyValue mapping) { } } [AutoRegisterExportedCollections] public partial class GameEntryPoint : Node { private IAssetRegistry? _textureRegistry; [Export] [RegisterExportedCollection(nameof(_textureRegistry), nameof(IRegistry.Registry))] private Godot.Collections.Array? _textureConfigs; public override void _Ready() { _textureRegistry ??= new TextureRegistry(); __RegisterExportedCollections_Generated(); } } ``` 为了让示例具备完整的调用路径,这里在 `_Ready()` 里先初始化了 `_textureRegistry`。 实际项目里,这个字段通常来自架构容器、服务定位或外部注入;关键点是调用 `__RegisterExportedCollections_Generated()` 之前,注册器成员必须已经可用,否则生成代码会按设计静默跳过注册。 ## 生成的代码 ```csharp // #nullable enable partial class GameEntryPoint { private void __RegisterExportedCollections_Generated() { if (this._textureConfigs is not null && this._textureRegistry is not null) { foreach (var __generatedItem in this._textureConfigs) { this._textureRegistry.Registry(__generatedItem); } } } } ``` ## 参数说明 ### `[AutoRegisterExportedCollections]` 类级标记,声明该类型允许生成 `__RegisterExportedCollections_Generated()`。 ### `[RegisterExportedCollection(registryMemberName, registerMethodName)]` | 参数 | 类型 | 说明 | |----------------------|----------|----------------------------------| | `registryMemberName` | `string` | 当前类型上用于执行注册的字段或属性名 | | `registerMethodName` | `string` | 注册方法名,例如 `Register` 或 `Registry` | 推荐优先使用 `nameof(...)` 表达式,而不是手写字符串。 ## 支持的匹配规则 生成器会在编译期验证: - 集合成员必须是实例字段,或可读的实例属性 - 集合类型必须可枚举 - 集合元素类型必须能在编译期推导 - 注册器成员必须是实例字段,或可读的实例属性 - 注册方法必须是单参数实例方法,且参数类型能接收集合元素类型 当前版本还支持从以下位置解析注册方法: - 注册器具体类型本身 - 注册器基类 - 注册器实现的接口 - 继承链上的接口 这意味着像 `IAssetRegistry` 继承 `IRegistry` 的项目结构也能正常生成,不必再把注册器字段改成具体实现类型。 ## 适用场景 推荐用于: - `GameEntryPoint` 中的资源注册 - 场景启动时的配置条目注册 - Inspector 预配置的纹理、音频、Prefab、场景映射批量接入 不推荐用于: - 注册前需要复杂过滤、去重、排序、条件判断的集合 - 需要记录失败项、错误聚合或回滚逻辑的批量导入 - 每个元素注册时都依赖额外上下文或副作用控制的流程 ## 使用约束 - 目标类型必须是 `partial class` - 不支持嵌套类 - 生成器不会自动调用 `__RegisterExportedCollections_Generated()` - 非泛型 `IEnumerable` 之类无法推导元素类型的集合不受支持 - 注册方法必须对宿主类型可访问 ## 诊断信息 | 诊断 ID | 含义 | |-----------------------|-------------------------------------------------------------| | `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 | | `GF_Common_Class_002` | 宿主类型已声明 `__RegisterExportedCollections_Generated()`,与生成代码冲突 | | `GF_AutoExport_001` | `AutoRegisterExportedCollections` 不支持嵌套类 | | `GF_AutoExport_002` | 指定的注册器成员不存在 | | `GF_AutoExport_003` | 注册器成员上找不到兼容的注册方法 | | `GF_AutoExport_004` | 被标记的成员不是可枚举集合 | | `GF_AutoExport_005` | 无法推导集合元素类型 | | `GF_AutoExport_006` | 集合成员不是实例可读成员 | | `GF_AutoExport_007` | 注册器成员不是实例可读成员 | | `GF_AutoExport_008` | `RegisterExportedCollectionAttribute` 参数无效 | ## 调用时机建议 推荐在以下时机之一调用生成方法: - `_Ready()` 中,且在注册器字段已经准备好之后 - 启动入口的显式 `Initialize()` 或 `Bootstrap()` 方法中 - 测试中的装配阶段 不要在构造函数中调用,因为此时 Godot 导出字段和外部依赖通常还未准备完毕。 ## 相关文档 - [源码生成器总览](./index) - [游戏内容配置系统](/zh-CN/game/config-system)