GFramework/GFramework.Ecs.Arch/INTEGRATION_PATTERN.md
GeWuYou fb14d7122c docs(style): 更新文档中的命名空间导入格式
- 将所有小写的命名空间导入更正为首字母大写格式
- 统一 GFramework 框架的命名空间引用规范
- 修复 core、ecs、godot 等模块的命名空间导入错误
- 标准化文档示例代码中的 using 语句格式
- 确保所有文档中的命名空间引用保持一致性
- 更新 global using 语句以匹配正确的命名空间格式
2026-03-10 07:18:49 +08:00

3.5 KiB
Raw Permalink Blame History

GFramework.Ecs.Arch - C# 标准集成方式

为什么不使用 ModuleInitializer

ModuleInitializer 在 C# 中主要用于:

  1. 应用程序代码 - 初始化应用程序级别的状态
  2. 高级源生成器 - 编译时代码生成

对于**库Library**来说,使用 ModuleInitializer 有以下问题:

  • 不符合 .NET 生态习惯
  • 缺乏显式控制
  • 难以测试和调试
  • 可能导致意外的副作用
  • 违反"显式优于隐式"原则

C# 中的标准做法

1. 依赖注入扩展方法(推荐)

这是 .NET 生态中最标准的做法,类似于:

  • ASP.NET Core: services.AddMvc()
  • Entity Framework: services.AddDbContext()
  • SignalR: services.AddSignalR()

优点:

  • 符合 .NET 生态习惯
  • 显式、可控
  • 易于测试
  • 支持配置
  • 支持链式调用

2. 使用方式

基本用法

public class MyArchitecture : Architecture
{
    protected override void OnConfigure()
    {
        // 显式添加 Arch ECS 支持
        Services.AddArch();
    }
}

带配置的用法

public class MyArchitecture : Architecture
{
    protected override void OnConfigure()
    {
        Services.AddArch(options =>
        {
            options.WorldCapacity = 2000;
            options.EnableStatistics = true;
            options.Priority = 50;
        });
    }
}

容器级别的用法

var container = new MicrosoftDiContainer();
container.AddArch(options =>
{
    options.WorldCapacity = 1000;
});

3. 对比其他方案

Spring Boot StarterJava

// Spring Boot 使用自动配置
@SpringBootApplication
public class Application {
    // 自动扫描并加载 starter
}

ASP.NET CoreC#

// .NET 使用显式注册
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSwagger();

C# 更倾向于显式注册,因为:

  1. 更清晰的依赖关系
  2. 更好的 IDE 支持
  3. 更容易调试和测试
  4. 避免"魔法"行为

4. 其他常见模式

4.1 Builder 模式

var architecture = new ArchitectureBuilder()
    .AddArch()
    .AddLogging()
    .Build();

4.2 Options 模式

services.Configure<ArchOptions>(options =>
{
    options.WorldCapacity = 2000;
});

4.3 静态工厂方法

var module = ArchEcsModule.Create(options =>
{
    options.WorldCapacity = 1000;
});

迁移指南

从 ModuleInitializer 迁移

之前(自动注册):

// 只需引入包,自动注册
// 无需任何代码

现在(显式注册):

public class MyArchitecture : Architecture
{
    protected override void OnConfigure()
{
        Services.AddArch();
    }
}

优势

  1. 更清晰 - 一眼就能看出使用了哪些模块
  2. 更可控 - 可以决定何时、如何注册
  3. 更灵活 - 可以传递配置参数
  4. 更标准 - 符合 .NET 生态习惯

总结

C# 生态更倾向于显式优于隐式的设计哲学,因此:

  • 推荐:使用扩展方法 AddArch()
  • 不推荐:使用 ModuleInitializer

这样的设计:

  1. 符合 .NET 生态习惯
  2. 提供更好的开发体验
  3. 更容易理解和维护
  4. 避免 CA2255 警告