# GFramework.Ecs.Arch - 从自动注册到显式注册的迁移 ## 变更原因 ### 问题:CA2255 警告 ``` warning CA2255: The 'ModuleInitializer' attribute is only intended to be used in application code or advanced source generator scenarios ``` ### 为什么 ModuleInitializer 不适合库? 在 C# 生态中,`ModuleInitializer` 主要用于: 1. **应用程序代码** - 初始化应用程序级别的状态 2. **高级源生成器** - 编译时代码生成 对于**库(Library)**来说,使用 `ModuleInitializer` 有以下问题: - ❌ 不符合 .NET 生态习惯 - ❌ 缺乏显式控制 - ❌ 难以测试和调试 - ❌ 可能导致意外的副作用 - ❌ 违反"显式优于隐式"原则 - ❌ 触发 CA2255 警告 ## C# 标准做法对比 ### Spring Boot(Java)- 自动配置 ```java @SpringBootApplication public class Application { // 自动扫描并加载 starter } ``` ### ASP.NET Core(C#)- 显式注册 ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); // 显式注册 builder.Services.AddSwagger(); // 显式注册 ``` **C# 更倾向于显式注册**,因为: 1. ✅ 更清晰的依赖关系 2. ✅ 更好的 IDE 支持 3. ✅ 更容易调试和测试 4. ✅ 避免"魔法"行为 ## 变更内容 ### 1. 移除 ModuleInitializer **之前:** ```csharp // ArchModuleInitializer.cs [ModuleInitializer] public static void Initialize() { ArchitectureModuleRegistry.Register(() => new ArchEcsModule(enabled: true)); } ``` **现在:** ```csharp // 文件已删除 ``` ### 2. 新增扩展方法 **新增:** ```csharp // ArchExtensions.cs public static class ArchExtensions { /// /// 添加 Arch ECS 支持到架构服务中 /// public static IArchitectureServices AddArch( this IArchitectureServices services, Action? configure = null) { var options = new ArchOptions(); configure?.Invoke(options); ArchitectureModuleRegistry.Register(() => new ArchEcsModule(enabled: true)); return services; } /// /// 添加 Arch ECS 支持到 IoC 容器中 /// public static IIocContainer AddArch( this IIocContainer container, Action? configure = null) { var options = new ArchOptions(); configure?.Invoke(options); ArchitectureModuleRegistry.Register(() => new ArchEcsModule(enabled: true)); return container; } } ``` ### 3. 更新使用方式 #### 之前(自动注册) ```csharp // 只需引入包,自动注册 // 无需任何代码 ``` #### 现在(显式注册) ```csharp public class MyArchitecture : Architecture { protected override void OnConfigure() { // 显式注册 Services.AddArch(); } } ``` #### 带配置 ```csharp public class MyArchitecture : Architecture { protected override void OnConfigure() { Services.AddArch(options => { options.WorldCapacity = 2000; options.EnableStatistics = true; options.Priority = 50; }); } } ``` ### 4. 更新测试 **之前:** ```csharp [Test] public void ArchEcsModule_Should_Be_Auto_Registered() { // 手动触发模块初始化器 ArchModuleInitializer.Initialize(); var services = new ArchitectureServices(); services.ModuleManager.RegisterBuiltInModules(...); // ... } ``` **现在:** ```csharp [Test] public void ArchEcsModule_Should_Be_Explicitly_Registered() { var services = new ArchitectureServices(); // 显式注册 services.AddArch(); services.ModuleManager.RegisterBuiltInModules(...); // ... } ``` ## 优势对比 ### 自动注册(ModuleInitializer) - ❌ 触发 CA2255 警告 - ❌ 不符合 .NET 生态习惯 - ❌ 缺乏显式控制 - ❌ 难以测试 - ❌ "魔法"行为 ### 显式注册(扩展方法) - ✅ 无警告 - ✅ 符合 .NET 生态习惯 - ✅ 显式、可控 - ✅ 易于测试 - ✅ 支持配置 - ✅ 支持链式调用 - ✅ 更好的 IDE 支持 ## 迁移指南 ### 对于现有用户 如果你之前使用自动注册方式,需要进行以下更改: **步骤 1:更新包** ```bash dotnet update package GeWuYou.GFramework.Ecs.Arch ``` **步骤 2:添加显式注册** ```csharp public class MyArchitecture : Architecture { protected override void OnConfigure() { // 添加这一行 Services.AddArch(); } } ``` **步骤 3:(可选)添加配置** ```csharp Services.AddArch(options => { options.WorldCapacity = 2000; options.EnableStatistics = true; }); ``` ## 验证结果 ### 构建验证 ✅ ```bash dotnet build GFramework.sln # Build succeeded. 39 Warning(s), 0 Error(s) # 无 CA2255 警告 ``` ### 测试验证 ✅ ```bash dotnet test --filter "ExplicitRegistrationTests" # Pas 4, Failed: 0, Total: 4 ``` **测试用例:** 1. ✅ `ArchEcsModule_Should_Be_Explicitly_Registered` - 验证显式注册 2. ✅ `World_Should_Be_Registered_In_Container` - 验证 World 注册 3. ✅ `AddArch_Should_Accept_Configuration` - 验证配置支持 4. ✅ `Container_AddArch_Should_Work` - 验证容器级别注册 ## 参考资料 ### .NET 生态中的类似实现 1. **ASP.NET Core** ```csharp services.AddMvc(); services.AddControllers(); ``` 2. **Entity Framework Core** ```csharp services.AddDbContext(); ``` 3. **SignalR** ```csharp services.AddSignalR(); ``` 4. **Swagger** ```csharp services.AddSwaggerGen(); ``` ### 相关文档 -N_PATTERN.md](INTEGRATION_PATTERN.md) - 集成模式详解 - [README.md](README.md) - 使用指南 - [CA2255 规则说明](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) ## 总结 通过从 `ModuleInitializer` 迁移到显式注册扩展方法: 1. ✅ **消除警告** - 不再触发 CA2255 2. ✅ **符合习惯** - 遵循 .NET 生态标准 3. ✅ **更好控制** - 显式、可配置 4. ✅ **易于测试** - 清晰的测试边界 5. ✅ **更好体验** - IDE 支持、链式调用 这是一个**破坏性变更**,但带来了更好的开发体验和更符合 .NET 生态的设计。 --- **变更日期:** 2026-03-08 **影响范围:** 所有使用 GFramework.Ecs.Arch 的项目 **迁移难度:** 低(只需添加一行代码)