refactor(ecs): 重构 Arch ECS 模块注册机制

- 移除自动初始化器,改用显式注册方式
- 修改 UseArch 扩展方法支持可选配置参数
- 更新文档说明新的集成方式和配置选项
- 删除自动注册相关的测试代码
- 调整 README 中的使用示例和架构说明
This commit is contained in:
GeWuYou 2026-03-08 20:19:24 +08:00
parent af76e0ab0b
commit bca92e52a3
4 changed files with 73 additions and 150 deletions

View File

@ -1,75 +0,0 @@
using System.Linq;
using Arch.Core;
using GFramework.Core.Abstractions.properties;
using GFramework.Core.architecture;
using GFramework.Core.ioc;
using GFramework.Ecs.Arch.Abstractions;
namespace GFramework.Ecs.Arch.Tests.integration;
/// <summary>
/// 自动注册集成测试
/// </summary>
[TestFixture]
public class AutoRegistrationTests
{
[SetUp]
public void Setup()
{
_container = new MicrosoftDiContainer();
_context = new ArchitectureContext(_container);
}
[TearDown]
public void TearDown()
{
_container?.Clear();
_context = null;
}
private MicrosoftDiContainer? _container;
private ArchitectureContext? _context;
/// <summary>
/// 测试 Arch ECS 模块是否自动注册
/// </summary>
[Test]
public void ArchEcsModule_Should_Be_Auto_Registered()
{
// Arrange - 手动触发模块初始化器(模拟自动注册)
ArchModuleInitializer.Initialize();
var services = new ArchitectureServices();
var properties = new ArchitectureProperties();
// Act
services.ModuleManager.RegisterBuiltInModules(services.Container, properties);
var modules = services.ModuleManager.GetModules();
// Assert
var archModule = modules.FirstOrDefault(m => m.ModuleName == nameof(ArchEcsModule));
Assert.That(archModule, Is.Not.Null, "ArchEcsModule should be auto-registered");
Assert.That(archModule, Is.InstanceOf<IArchEcsModule>());
}
/// <summary>
/// 测试 World 是否正确注册到容器
/// </summary>
[Test]
public void World_Should_Be_Registered_In_Container()
{
// Arrange - 手动触发模块初始化器
ArchModuleInitializer.Initialize();
var services = new ArchitectureServices();
var properties = new ArchitectureProperties();
// Act
services.ModuleManager.RegisterBuiltInModules(services.Container, properties);
services.ModuleManager.InitializeAllAsync(false).Wait();
// Assert
var world = services.Container.Get<World>();
Assert.That(world, Is.Not.Null, "World should be registered in container");
}
}

View File

@ -1,21 +0,0 @@
using System.Runtime.CompilerServices;
using GFramework.Core.Abstractions.architecture;
namespace GFramework.Ecs.Arch;
/// <summary>
/// Arch ECS 模块自动初始化器
/// 使用 ModuleInitializer 特性在程序启动时自动注册模块
/// </summary>
public static class ArchModuleInitializer
{
/// <summary>
/// 模块初始化方法,在程序启动时自动调用
/// </summary>
[ModuleInitializer]
public static void Initialize()
{
// 注册 Arch ECS 模块工厂
ArchitectureModuleRegistry.Register(() => new ArchEcsModule(enabled: true));
}
}

View File

@ -4,7 +4,7 @@ GFramework 的 Arch ECS 集成包,提供开箱即用的 ECSEntity Component
## 特性
- 🚀 **自动集成** - 引入 NuGet 包即可自动启用,无需手动配置
- 🎯 **显式集成** - 符合 .NET 生态习惯的显式注册方式
- 🔌 **零依赖** - 不使用时Core 包无 Arch 依赖
- 🎯 **类型安全** - 完整的类型系统和编译时检查
- ⚡ **高性能** - 基于 Arch ECS 的高性能实现
@ -18,7 +18,29 @@ GFramework 的 Arch ECS 集成包,提供开箱即用的 ECSEntity Component
dotnet add package GeWuYou.GFramework.Ecs.Arch
```
### 2. 创建组件
### 2. 注册 ECS 模块
```csharp
// 在架构初始化时添加 Arch ECS 支持
var architecture = new GameArchitecture(config)
.UseArch(); // 添加 ECS 支持
architecture.Initialize();
```
### 3. 带配置的注册
```csharp
var architecture = new GameArchitecture(config)
.UseArch(options =>
{
options.WorldCapacity = 2000;
options.EnableStatistics = true;
options.Priority = 50;
});
architecture.Initialize();
```
```csharp
using System.Runtime.InteropServices;
@ -38,7 +60,7 @@ public struct Velocity(float x, float y)
}
```
### 3. 创建系统
### 5. 创建系统
```csharp
using Arch.Core;
@ -65,7 +87,7 @@ public sealed class MovementSystem : ArchSystemAdapter<float>
}
```
### 4. 注册系统
### 6. 注册系统
```csharp
public class MyArchitecture : Architecture
@ -77,7 +99,7 @@ public class MyArchitecture : Architecture
}
```
### 5. 创建实体
### 7. 创建实体
```csharp
var world = this.GetService<World>();
@ -87,7 +109,7 @@ var entity = world.Create(
);
```
### 6. 更新系统
### 8. 更新系统
```csharp
var ecsModule = this.GetService<IArchEcsModule>();
@ -96,12 +118,11 @@ ecsModule.Update(deltaTime);
## 配置选项
可以通过配置文件或代码配置 Arch ECS
### 代码配置
```csharp
services.ConfigureArch(options =>
var architecture = new GameArchitecture(config)
.UseArch(options =>
{
options.WorldCapacity = 2000;
options.EnableStatistics = true;
@ -109,37 +130,38 @@ services.ConfigureArch(options =>
});
```
### 配置文件
### 配置说明
```json
{
"GFramework": {
"Modules": {
"Arch": {
"Enabled": true,
"Priority": 50,
"WorldCapacity": 1000,
"EnableStatistics": false
}
}
}
}
```
- `WorldCapacity` - World 初始容量默认1000
- `EnableStatistics` - 是否启用统计信息默认false
- `Priority` - 模块优先级默认50
## 架构说明
### 模块自动注册
### 显式注册模式
本包使用 `ModuleInitializer` 特性实现自动注册,无需手动配置
本包采用 .NET 生态标准的显式注册模式,基于架构实例:
**优点:**
- ✅ 符合 .NET 生态习惯
- ✅ 显式、可控
- ✅ 易于测试和调试
- ✅ 支持配置
- ✅ 支持链式调用
- ✅ 避免"魔法"行为
**使用方式:**
```csharp
[ModuleInitializer]
public static void Initialize()
{
ArchitectureModuleRegistry.Register(() => new ArchEcsModule(enabled: true));
}
// 在架构初始化时添加
var architecture = new GameArchitecture(config)
.UseArch(); // 显式注册
architecture.Initialize();
```
详见:[INTEGRATION_PATTERN.md](INTEGRATION_PATTERN.md)
### 系统适配器
`ArchSystemAdapter<T>` 桥接 Arch.System.ISystem<T> 到 GFramework 架构:

View File

@ -1,5 +1,4 @@
using GFramework.Core.Abstractions.architecture;
using Microsoft.Extensions.DependencyInjection;
namespace GFramework.Ecs.Arch.extensions;
@ -9,26 +8,24 @@ namespace GFramework.Ecs.Arch.extensions;
public static class ArchExtensions
{
/// <summary>
/// 配置 Arch ECS 选项
/// 添加 Arch ECS 支持到架构中
/// </summary>
public static IServiceCollection ConfigureArch(
this IServiceCollection services,
Action<ArchOptions> configure)
{
var options = new ArchOptions();
configure(options);
services.AddSingleton(options);
return services;
}
/// <summary>
/// 显式启用 Arch ECS 模块(备选方案)
/// </summary>
public static TArchitecture UseArch<TArchitecture>(this TArchitecture architecture)
/// <typeparam name="TArchitecture">架构类型</typeparam>
/// <param name="architecture">架构实例</param>
/// <param name="configure">可选的配置委托</param>
/// <returns>架构实例,支持链式调用</returns>
public static TArchitecture UseArch<TArchitecture>(
this TArchitecture architecture,
Action<ArchOptions>? configure = null)
where TArchitecture : IArchitecture
{
// 此方法为显式注册提供支持
// 实际注册由 ModuleInitializer 自动完成
// 配置选项
var options = new ArchOptions();
configure?.Invoke(options);
// 注册模块
ArchitectureModuleRegistry.Register(() => new ArchEcsModule(enabled: true));
return architecture;
}
}