Skip to content

refactor(architecture): 重构架构类为模块化设计提升代码安全性#112

Merged
GeWuYou merged 2 commits into
mainfrom
refactor/architecture-modular-safety
Mar 17, 2026
Merged

refactor(architecture): 重构架构类为模块化设计提升代码安全性#112
GeWuYou merged 2 commits into
mainfrom
refactor/architecture-modular-safety

Conversation

@GeWuYou
Copy link
Copy Markdown
Owner

@GeWuYou GeWuYou commented Mar 17, 2026

  • 将单一 Architecture 类拆分为 ArchitectureLifecycle、ArchitectureComponentRegistry 和 ArchitectureModules
  • 消除 3 处 null! 强制断言,在构造函数中初始化管理器提高代码安全性
  • 添加 PhaseChanged 事件支持架构阶段监听
  • 所有公共 API 保持不变确保向后兼容
  • 实现单一职责原则使代码更易维护和测试
  • 组件注册、生命周期管理和模块管理职责分离到专门的管理器中

Summary by Sourcery

将核心的 Architecture 类重构为一个模块化的协调器,通过专门的管理类来委托生命周期管理、组件注册和模块管理,同时保持现有的公共 API 不变。

Enhancements:

  • 引入 ArchitectureLifecycle,用于封装架构阶段管理、组件初始化/销毁以及就绪状态跟踪,并新增 PhaseChanged 事件。
  • 引入 ArchitectureComponentRegistry,用于集中管理系统、模型和工具的注册与生命周期绑定,包括基于依赖注入(DI)的类型注册。
  • 引入 ArchitectureModules,用于处理架构模块安装和中介者行为注册,将这些关注点从核心 Architecture 类中解耦出来。
  • 在 Architecture 的构造函数中初始化生命周期、组件注册表、模块管理器和日志记录,以消除可空断言并确保实例在构造完成时即为完整可用。
  • 通过在 Architecture 中委托给新的生命周期管理器,对外暴露生命周期状态(CurrentPhase、IsReady、WaitUntilReadyAsync、Destroy/DestroyAsync),从而保持向后兼容性。

Documentation:

  • 重写并重构 Architecture 文档,以说明新的模块化内部设计、生命周期阶段和事件钩子,并包含更新后的示意图和使用流程。
  • 更新核心索引文档,以反映 v1.1.0 的架构重构、生命周期阶段细节和变更日志,同时保持公共 API 使用指南不变。

Tests:

  • 调整 Architecture 测试基类,通过新的 PhaseChanged 事件记录阶段历史,而不是重写阶段切换行为。

Chores:

  • 将文档中记录的框架版本提升到 v1.1.0,并更新对应的更新时间和变更日志条目,以说明架构重构和安全性改进。
Original summary in English

Summary by Sourcery

Refactor the core Architecture class into a modular coordinator that delegates lifecycle, component registration, and module management to dedicated manager classes while preserving the public API.

Enhancements:

  • Introduce ArchitectureLifecycle to encapsulate architecture phase management, component initialization/destruction, and ready-state tracking with a new PhaseChanged event.
  • Introduce ArchitectureComponentRegistry to centralize registration and lifecycle wiring of systems, models, and utilities, including DI-based type registration.
  • Introduce ArchitectureModules to handle architecture module installation and mediator behavior registration, decoupling these concerns from the core Architecture class.
  • Initialize lifecycle, component registry, module manager, and logging in the Architecture constructor to eliminate nullable assertions and ensure fully constructed instances.
  • Expose lifecycle state through Architecture (CurrentPhase, IsReady, WaitUntilReadyAsync, Destroy/DestroyAsync) by delegating to the new lifecycle manager, maintaining backward compatibility.

Documentation:

  • Rewrite and restructure the Architecture documentation to describe the new modular internal design, lifecycle phases, and event hooks, including updated diagrams and usage flows.
  • Update the core index documentation to reflect the v1.1.0 architecture refactor, lifecycle phase details, and changelog while keeping the public API usage guidance intact.

Tests:

  • Adjust Architecture test base to record phase history via the new PhaseChanged event instead of overriding phase transition behavior.

Chores:

  • Bump documented framework version to v1.1.0 with corresponding update date and changelog entries describing the architecture refactor and safety improvements.

- 将单一 Architecture 类拆分为 ArchitectureLifecycle、ArchitectureComponentRegistry 和 ArchitectureModules
- 消除 3 处 null! 强制断言,在构造函数中初始化管理器提高代码安全性
- 添加 PhaseChanged 事件支持架构阶段监听
- 所有公共 API 保持不变确保向后兼容
- 实现单一职责原则使代码更易维护和测试
- 组件注册、生命周期管理和模块管理职责分离到专门的管理器中
@deepsource-io
Copy link
Copy Markdown

deepsource-io Bot commented Mar 17, 2026

DeepSource Code Review

We reviewed changes in ef05713...1c2e68f on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
C# Mar 17, 2026 4:50a.m. Review ↗
Secrets Mar 17, 2026 4:50a.m. Review ↗

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 17, 2026

审阅者指南

在保持公共 API 稳定的前提下,将核心 Architecture 类重构为“协调器 + 管理器”(生命周期、组件注册表、模块)的模块化设计;改进生命周期安全性,新增 PhaseChanged 事件,并更新文档/测试以符合新的架构以及构造期初始化语义。

Architecture 初始化生命周期时序图(v1.1.0)

sequenceDiagram
    actor App
    participant Arch as Architecture
    participant Lifecycle as ArchitectureLifecycle
    participant Services as IArchitectureServices
    participant Container as IIocContainer
    participant Env as IEnvironment
    participant Modules as IArchitectureModuleManager
    participant UserArch as DerivedArchitecture
    participant Util as IContextUtility
    participant Model as IModel
    participant Sys as ISystem

    App->>Arch: new DerivedArchitecture(configuration, environment, services, context)
    activate Arch
    Arch->>Arch: constructor
    Arch->>Arch: LoggerFactoryResolver.Provider = configuration.LoggerProperties.LoggerFactoryProvider
    Arch->>Arch: _logger = CreateLogger()
    Arch->>Lifecycle: new ArchitectureLifecycle(Arch, configuration, services, _logger)
    Arch->>Arch: _lifecycle = Lifecycle
    Arch->>Arch: _componentRegistry = new ArchitectureComponentRegistry(...)
    Arch->>Arch: _modules = new ArchitectureModules(...)
    deactivate Arch

    App->>Arch: InitializeAsync()
    activate Arch
    Arch->>Arch: InitializeInternalAsync(asyncMode:true)

    Arch->>Env: Initialize()
    activate Env
    Env-->>Arch: done
    deactivate Env

    Arch->>Modules: RegisterBuiltInModules(Services.Container)
    activate Modules
    Modules-->>Arch: done
    deactivate Modules

    Arch->>Container: Contains<IEnvironment>()
    alt not registered
        Arch->>Container: RegisterPlurality(Environment)
    end

    Arch->>Arch: _context = new ArchitectureContext(Services.Container)
    Arch->>Arch: GameContext.Bind(GetType(), _context)
    Arch->>Services: set Context on internal services

    Arch->>Container: ExecuteServicesHook(Configurator)

    Arch->>Modules: InitializeAllAsync(asyncMode:true)
    Modules-->>Arch: done

    Arch->>UserArch: OnInitialize()
    activate UserArch
    UserArch->>Arch: RegisterUtility(Util)
    Arch->>Arch: _componentRegistry.RegisterUtility(Util)
    Arch->>Util: IfType<IContextUtility>.SetContext(Context)
    Arch->>Lifecycle: RegisterLifecycleComponent(Util)
    UserArch->>Arch: RegisterModel(Model)
    Arch->>Arch: _componentRegistry.RegisterModel(Model)
    Arch->>Model: SetContext(Context)
    Arch->>Lifecycle: RegisterLifecycleComponent(Model)
    UserArch->>Arch: RegisterSystem(Sys)
    Arch->>Arch: _componentRegistry.RegisterSystem(Sys)
    Arch->>Sys: SetContext(Context)
    Arch->>Lifecycle: RegisterLifecycleComponent(Sys)
    deactivate UserArch

    Arch->>Lifecycle: InitializeAllComponentsAsync(asyncMode:true)
    activate Lifecycle
    Lifecycle->>Lifecycle: EnterPhase(BeforeUtilityInit)
    Lifecycle->>Util: InitializeAsync()
    Util-->>Lifecycle: done
    Lifecycle->>Lifecycle: EnterPhase(AfterUtilityInit)

    Lifecycle->>Lifecycle: EnterPhase(BeforeModelInit)
    Lifecycle->>Model: InitializeAsync() or Initialize()
    Model-->>Lifecycle: done
    Lifecycle->>Lifecycle: EnterPhase(AfterModelInit)

    Lifecycle->>Lifecycle: EnterPhase(BeforeSystemInit)
    Lifecycle->>Sys: InitializeAsync() or Initialize()
    Sys-->>Lifecycle: done
    Lifecycle->>Lifecycle: EnterPhase(AfterSystemInit)
    Lifecycle-->>Arch: all components initialized
    deactivate Lifecycle

    Arch->>Container: Freeze()
    Arch->>Lifecycle: MarkAsReady()
    activate Lifecycle
    Lifecycle->>Lifecycle: EnterPhase(Ready)
    Lifecycle->>Lifecycle: _readyTcs.TrySetResult()
    deactivate Lifecycle

    Arch-->>App: InitializeAsync completed
    deactivate Arch

    App->>Arch: WaitUntilReadyAsync()
    Arch->>Lifecycle: WaitUntilReadyAsync()
    Lifecycle-->>Arch: completed Task (already Ready)
    Arch-->>App: return
Loading

模块化 Architecture 协调器与管理器的类图

classDiagram
    direction LR

    class IArchitecture {
    <<interface>>
    +ArchitecturePhase CurrentPhase
    +IArchitectureContext Context
    +bool IsReady
    +void Initialize()
    +Task InitializeAsync()
    +ValueTask DestroyAsync()
    +void Destroy()
    +TSystem RegisterSystem~TSystem~(TSystem system)
    +void RegisterSystem~T~(Action~T~ onCreated)
    +TModel RegisterModel~TModel~(TModel model)
    +void RegisterModel~T~(Action~T~ onCreated)
    +TUtility RegisterUtility~TUtility~(TUtility utility)
    +void RegisterUtility~T~(Action~T~ onCreated)
    +IArchitectureModule InstallModule(IArchitectureModule module)
    +IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
    +Task WaitUntilReadyAsync()
    +event PhaseChanged(ArchitecturePhase phase)
    }

    class Architecture {
    -IArchitectureConfiguration Configuration
    -IEnvironment Environment
    -IArchitectureServices Services
    -ILogger _logger
    -IArchitectureContext _context
    -ArchitectureLifecycle _lifecycle
    -ArchitectureComponentRegistry _componentRegistry
    -ArchitectureModules _modules
    +ArchitecturePhase CurrentPhase
    +IArchitectureContext Context
    +bool IsReady
    +Action~IServiceCollection~ Configurator
    +event PhaseChanged(ArchitecturePhase phase)
    +Architecture(IArchitectureConfiguration configuration, IEnvironment environment, IArchitectureServices services, IArchitectureContext context)
    +IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
    +void RegisterMediatorBehavior~TBehavior~()
    +IArchitectureModule InstallModule(IArchitectureModule module)
    +TSystem RegisterSystem~TSystem~(TSystem system)
    +void RegisterSystem~T~(Action~T~ onCreated)
    +TModel RegisterModel~TModel~(TModel model)
    +void RegisterModel~T~(Action~T~ onCreated)
    +TUtility RegisterUtility~TUtility~(TUtility utility)
    +void RegisterUtility~T~(Action~T~ onCreated)
    +void Initialize()
    +Task InitializeAsync()
    +Task WaitUntilReadyAsync()
    +ValueTask DestroyAsync()
    +void Destroy()
    #void OnInitialize()
    }

    class ArchitectureLifecycle {
    -IArchitecture _architecture
    -IArchitectureConfiguration _configuration
    -IArchitectureServices _services
    -ILogger _logger
    -TaskCompletionSource _readyTcs
    -HashSet~IInitializable~ _pendingInitializableSet
    -List~IInitializable~ _pendingInitializableList
    -HashSet~object~ _disposableSet
    -List~object~ _disposables
    -List~IArchitectureLifecycleHook~ _lifecycleHooks
    -bool _initialized
    +ArchitecturePhase CurrentPhase
    +bool IsReady
    +bool IsInitialized
    +event PhaseChanged(ArchitecturePhase phase)
    +ArchitectureLifecycle(IArchitecture architecture, IArchitectureConfiguration configuration, IArchitectureServices services, ILogger logger)
    +IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
    +void RegisterLifecycleComponent~T~(T component)
    +void EnterPhase(ArchitecturePhase next)
    +Task InitializeAllComponentsAsync(bool asyncMode)
    +ValueTask DestroyAsync()
    +void Destroy()
    +void MarkAsReady()
    +void MarkAsFailed(Exception exception)
    +Task WaitUntilReadyAsync()
    }

    class ArchitectureComponentRegistry {
    -IArchitecture architecture
    -IArchitectureConfiguration configuration
    -IArchitectureServices services
    -ArchitectureLifecycle lifecycle
    -ILogger logger
    +ArchitectureComponentRegistry(IArchitecture architecture, IArchitectureConfiguration configuration, IArchitectureServices services, ArchitectureLifecycle lifecycle, ILogger logger)
    +TSystem RegisterSystem~TSystem~(TSystem system)
    +void RegisterSystem~T~(Action~T~ onCreated)
    +TModel RegisterModel~TModel~(TModel model)
    +void RegisterModel~T~(Action~T~ onCreated)
    +TUtility RegisterUtility~TUtility~(TUtility utility)
    +void RegisterUtility~T~(Action~T~ onCreated)
    }

    class ArchitectureModules {
    -IArchitecture architecture
    -IArchitectureServices services
    -ILogger logger
    +ArchitectureModules(IArchitecture architecture, IArchitectureServices services, ILogger logger)
    +void RegisterMediatorBehavior~TBehavior~()
    +IArchitectureModule InstallModule(IArchitectureModule module)
    }

    class IArchitectureLifecycleHook {
    <<interface>>
    +void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
    }

    class IArchitecturePhaseListener {
    <<interface>>
    +void OnArchitecturePhase(ArchitecturePhase phase)
    }

    class IArchitectureModule {
    <<interface>>
    +void Install(IArchitecture architecture)
    }

    class IArchitectureServices {
    <<interface>>
    +IIocContainer Container
    +IArchitectureModuleManager ModuleManager
    }

    class IIocContainer {
    <<interface>>
    +void RegisterPlurality~T~(T instance)
    +void RegisterFactory~T~(Func~IServiceProvider,T~ factory)
    +IEnumerable~T~ GetAll~T~()
    +bool Contains~T~()
    +void RegisterMediatorBehavior~TBehavior~()
    +void ExecuteServicesHook(Action~IServiceCollection~ configurator)
    +void Freeze()
    +void Clear()
    }

    class IArchitectureModuleManager {
    <<interface>>
    +void RegisterBuiltInModules(IIocContainer container)
    +Task InitializeAllAsync(bool asyncMode)
    +ValueTask DestroyAllAsync()
    }

    class IModel {
    <<interface>>
    +void SetContext(IArchitectureContext context)
    }

    class ISystem {
    <<interface>>
    +void SetContext(IArchitectureContext context)
    }

    class IUtility {
    <<interface>>
    }

    class IContextUtility {
    <<interface>>
    +void SetContext(IArchitectureContext context)
    }

    class IInitializable {
    <<interface>>
    +void Initialize()
    }

    class IAsyncInitializable {
    <<interface>>
    +Task InitializeAsync()
    }

    class IDestroyable {
    <<interface>>
    +void Destroy()
    }

    class IAsyncDestroyable {
    <<interface>>
    +ValueTask DestroyAsync()
    }

    IArchitecture <|.. Architecture

    Architecture --> ArchitectureLifecycle : composes
    Architecture --> ArchitectureComponentRegistry : composes
    Architecture --> ArchitectureModules : composes
    Architecture --> IArchitectureServices : uses
    Architecture --> IEnvironment : uses

    ArchitectureLifecycle --> IArchitecture : coordinates
    ArchitectureLifecycle --> IArchitectureServices : uses
    ArchitectureLifecycle --> IArchitectureLifecycleHook : manages
    ArchitectureLifecycle --> IArchitecturePhaseListener : notifies
    ArchitectureLifecycle --> IInitializable : manages
    ArchitectureLifecycle --> IAsyncInitializable : manages
    ArchitectureLifecycle --> IDestroyable : manages
    ArchitectureLifecycle --> IAsyncDestroyable : manages

    ArchitectureComponentRegistry --> IArchitecture : uses
    ArchitectureComponentRegistry --> IArchitectureServices : uses
    ArchitectureComponentRegistry --> ArchitectureLifecycle : uses
    ArchitectureComponentRegistry --> IModel : registers
    ArchitectureComponentRegistry --> ISystem : registers
    ArchitectureComponentRegistry --> IUtility : registers
    ArchitectureComponentRegistry --> IContextUtility : registers

    ArchitectureModules --> IArchitecture : uses
    ArchitectureModules --> IArchitectureServices : uses
    ArchitectureModules --> IArchitectureModule : installs

    IArchitectureServices --> IIocContainer : has
    IArchitectureServices --> IArchitectureModuleManager : has

    IContextUtility --|> IUtility
    IAsyncInitializable --|> IInitializable
    IAsyncDestroyable --|> IDestroyable
Loading

文件级变更

Change Details Files
将 Architecture 重构为一个协调器,将生命周期、组件注册、模块管理委托给专用管理器类,实现更安全的构造期初始化,并新增 PhaseChanged 事件。
  • 用新的构造函数替换了原有的 Architecture 主构造函数,在构造阶段立即初始化 configuration、environment、services、logger,以及三个新的管理器实例:ArchitectureLifecycle、ArchitectureComponentRegistry 和 ArchitectureModules。
  • 将与生命周期相关的职责(阶段跟踪、校验、阶段通知、组件初始化/销毁队列、就绪状态 TaskCompletionSource)从 Architecture 中抽离到新的 ArchitectureLifecycle 类中。
  • 将系统、模型与工具类(包括上下文注入、生命周期注册与基于工厂的依赖注入注册)的组件注册逻辑移动到 ArchitectureComponentRegistry 中。
  • 将中介行为注册与模块安装逻辑移动到 ArchitectureModules 中,并更新 Architecture 以委托对应的公共方法。
  • 用对新管理器类的调用替换 Architecture 中直接访问字段/状态的用法(例如 CurrentPhase、IsReady、WaitUntilReadyAsync、Destroy/DestroyAsync、中介行为注册、模块安装和组件注册 API),同时保持方法签名不变以保证向后兼容。
  • 通过在 Architecture 构造函数中完整初始化依赖并在可能情况下将 logger/context 字段设为 readonly,移除了空抑制运算符的使用(例如在 logger/context 字段上)。
  • 用 ArchitectureLifecycle.MarkAsFailed 替换内联的初始化失败处理逻辑,用 ArchitectureLifecycle.MarkAsReady 实现就绪信号。
GFramework.Core/Architectures/Architecture.cs
GFramework.Core/Architectures/ArchitectureLifecycle.cs
GFramework.Core/Architectures/ArchitectureComponentRegistry.cs
GFramework.Core/Architectures/ArchitectureModules.cs
引入 ArchitectureLifecycle,作为专用的生命周期管理器,负责阶段管理、组件初始化/销毁以及就绪状态跟踪。
  • 实现 ArchitectureLifecycle 以持有 ArchitecturePhase 状态、就绪标记、生命周期钩子和阶段感知的通知逻辑,并使用 IArchitectureServices.Container 解析 IArchitecturePhaseListener 实例。
  • 实现阶段变更校验逻辑,遵循 ArchitectureConfiguration.ArchitectureProperties.StrictPhaseValidation 配置,并允许从任意阶段切换到 ArchitecturePhase.FailedInitialization。
  • 实现组件生命周期注册逻辑,跟踪用于分阶段初始化的 IInitializable 组件,并跟踪实现了 IDestroyable 或 IAsyncDestroyable 的组件以支持逆序销毁。
  • 实现 InitializeAllComponentsAsync,用于按类型(IContextUtility、IModel、ISystem)对待初始化组件分组,在工具/模型/系统初始化前后进入对应的 Before*/After* 阶段,并根据实际情况调用 Initialize/InitializeAsync。
  • 实现 DestroyAsync/Destroy,以防止重复销毁,设置 Destroying/Destroyed 阶段,异步销毁所有被跟踪的可销毁对象,销毁服务模块并清空容器。
  • 实现就绪相关 API(MarkAsReady、MarkAsFailed、WaitUntilReadyAsync),由 TaskCompletionSource 支持,并与新的 PhaseChanged 事件协同工作。
GFramework.Core/Architectures/ArchitectureLifecycle.cs
引入 ArchitectureComponentRegistry,用于封装并校验系统、模型和工具类的注册。
  • 实现系统、模型和工具类的注册方法,对照生命周期阶段和配置(AllowLateRegistration)进行校验;设置组件上下文,将组件注册进 IoC 容器,并将其注册到 ArchitectureLifecycle 中以进行初始化/销毁管理。
  • 实现基于 ActivatorUtilities.CreateInstance 的系统/模型/工具类型的工厂注册,并在核心装配完成后调用可选的用户回调 onCreated。
  • 使用类型安全的辅助方法(例如 IfType)仅对需要上下文的工具类应用上下文/生命周期装配。
GFramework.Core/Architectures/ArchitectureComponentRegistry.cs
引入 ArchitectureModules,用于封装模块安装和中介行为注册。
  • 实现 RegisterMediatorBehavior,记录日志并委托给 services.Container.RegisterMediatorBehavior。
  • 实现 InstallModule,记录模块安装日志,调用 module.Install(architecture),并返回该模块实例。
  • 更新 Architecture,使其在公共的 RegisterMediatorBehavior 和 InstallModule API 中委托给 ArchitectureModules。
GFramework.Core/Architectures/ArchitectureModules.cs
GFramework.Core/Architectures/Architecture.cs
更新测试以使用新的 PhaseChanged 事件,而不再通过覆写阶段切换来测试。
  • 修改 TestArchitectureBase,在 OnInitialize 中订阅 Architecture.PhaseChanged 事件,并将阶段追加到 PhaseHistory,而不是覆写 EnterPhase。
  • 确保测试中的 InitCalled 标志与注册后钩子的行为保持不变。
GFramework.Core.Tests/Architectures/TestArchitectureBase.cs
修订并精简 Architecture 核心文档,以匹配新的模块化设计和生命周期语义,并在核心索引文档中新增内部结构章节。
  • 重写 docs/zh-CN/core/architecture.md,从一篇偏重 API 使用的大型指南,改为更聚焦的架构概览,解释设计目标、核心组件、类图、生命周期阶段、初始化与销毁流程以及新的基于管理器的设计。
  • 文档中说明 Architecture 现在组合了 ArchitectureLifecycle、ArchitectureComponentRegistry 和 ArchitectureModules,并指出这些管理器会在构造函数中创建,以保证安全性和即刻可用。
  • 新增 PhaseChanged 事件的文档,并给出如何订阅生命周期变化以及如何实现 IArchitectureLifecycleHook 的示例。
  • 更新 docs/zh-CN/core/index.md,描述包含 FailedInitialization 在内的 11 阶段生命周期,说明 Architecture(v1.1.0+)的新的模块化结构,并更新初始化流程图以反映构造期创建管理器的过程。
  • 新增版本化变更日志(v1.1.0),并标明关键行为变更在公共 API 层面保持向后兼容。
docs/zh-CN/core/architecture.md
docs/zh-CN/core/index.md

提示与命令

与 Sourcery 交互

  • 触发新的代码审阅: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub Issue: 在审阅评论下回复,要求 Sourcery 从该评论创建一个 Issue。你也可以直接在评论中回复 @sourcery-ai issue 来从该评论创建 Issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 Pull Request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 描述正文任意位置写上 @sourcery-ai summary,即可在指定位置生成 PR 摘要。你也可以评论 @sourcery-ai summary 来随时(重新)生成摘要。
  • 生成审阅者指南: 在 Pull Request 中评论 @sourcery-ai guide,即可随时(重新)生成审阅者指南。
  • 一次性解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不希望再看到它们,这会很有用。
  • 撤销所有 Sourcery 审阅: 在 Pull Request 中评论 @sourcery-ai dismiss,可撤销所有现有的 Sourcery 审阅。如果你想以一次全新的审阅开始,这尤其有用——记得随后评论 @sourcery-ai review 来触发新的审阅!

自定义你的体验

访问你的 控制台 可以:

  • 启用或禁用某些审阅功能,例如 Sourcery 生成的 Pull Request 摘要、审阅者指南等。
  • 更改审阅语言。
  • 添加、移除或编辑自定义审阅指令。
  • 调整其它审阅相关设置。

获取帮助

Original review guide in English

Reviewer's Guide

Refactors the core Architecture class into a modular coordinator-plus-managers design (lifecycle, component registry, modules) while keeping the public APIs stable, improving lifecycle safety, adding a PhaseChanged event, and updating docs/tests to match the new architecture and construction-time initialization semantics.

Sequence diagram for Architecture initialization lifecycle (v1.1.0)

sequenceDiagram
    actor App
    participant Arch as Architecture
    participant Lifecycle as ArchitectureLifecycle
    participant Services as IArchitectureServices
    participant Container as IIocContainer
    participant Env as IEnvironment
    participant Modules as IArchitectureModuleManager
    participant UserArch as DerivedArchitecture
    participant Util as IContextUtility
    participant Model as IModel
    participant Sys as ISystem

    App->>Arch: new DerivedArchitecture(configuration, environment, services, context)
    activate Arch
    Arch->>Arch: constructor
    Arch->>Arch: LoggerFactoryResolver.Provider = configuration.LoggerProperties.LoggerFactoryProvider
    Arch->>Arch: _logger = CreateLogger()
    Arch->>Lifecycle: new ArchitectureLifecycle(Arch, configuration, services, _logger)
    Arch->>Arch: _lifecycle = Lifecycle
    Arch->>Arch: _componentRegistry = new ArchitectureComponentRegistry(...)
    Arch->>Arch: _modules = new ArchitectureModules(...)
    deactivate Arch

    App->>Arch: InitializeAsync()
    activate Arch
    Arch->>Arch: InitializeInternalAsync(asyncMode:true)

    Arch->>Env: Initialize()
    activate Env
    Env-->>Arch: done
    deactivate Env

    Arch->>Modules: RegisterBuiltInModules(Services.Container)
    activate Modules
    Modules-->>Arch: done
    deactivate Modules

    Arch->>Container: Contains<IEnvironment>()
    alt not registered
        Arch->>Container: RegisterPlurality(Environment)
    end

    Arch->>Arch: _context = new ArchitectureContext(Services.Container)
    Arch->>Arch: GameContext.Bind(GetType(), _context)
    Arch->>Services: set Context on internal services

    Arch->>Container: ExecuteServicesHook(Configurator)

    Arch->>Modules: InitializeAllAsync(asyncMode:true)
    Modules-->>Arch: done

    Arch->>UserArch: OnInitialize()
    activate UserArch
    UserArch->>Arch: RegisterUtility(Util)
    Arch->>Arch: _componentRegistry.RegisterUtility(Util)
    Arch->>Util: IfType<IContextUtility>.SetContext(Context)
    Arch->>Lifecycle: RegisterLifecycleComponent(Util)
    UserArch->>Arch: RegisterModel(Model)
    Arch->>Arch: _componentRegistry.RegisterModel(Model)
    Arch->>Model: SetContext(Context)
    Arch->>Lifecycle: RegisterLifecycleComponent(Model)
    UserArch->>Arch: RegisterSystem(Sys)
    Arch->>Arch: _componentRegistry.RegisterSystem(Sys)
    Arch->>Sys: SetContext(Context)
    Arch->>Lifecycle: RegisterLifecycleComponent(Sys)
    deactivate UserArch

    Arch->>Lifecycle: InitializeAllComponentsAsync(asyncMode:true)
    activate Lifecycle
    Lifecycle->>Lifecycle: EnterPhase(BeforeUtilityInit)
    Lifecycle->>Util: InitializeAsync()
    Util-->>Lifecycle: done
    Lifecycle->>Lifecycle: EnterPhase(AfterUtilityInit)

    Lifecycle->>Lifecycle: EnterPhase(BeforeModelInit)
    Lifecycle->>Model: InitializeAsync() or Initialize()
    Model-->>Lifecycle: done
    Lifecycle->>Lifecycle: EnterPhase(AfterModelInit)

    Lifecycle->>Lifecycle: EnterPhase(BeforeSystemInit)
    Lifecycle->>Sys: InitializeAsync() or Initialize()
    Sys-->>Lifecycle: done
    Lifecycle->>Lifecycle: EnterPhase(AfterSystemInit)
    Lifecycle-->>Arch: all components initialized
    deactivate Lifecycle

    Arch->>Container: Freeze()
    Arch->>Lifecycle: MarkAsReady()
    activate Lifecycle
    Lifecycle->>Lifecycle: EnterPhase(Ready)
    Lifecycle->>Lifecycle: _readyTcs.TrySetResult()
    deactivate Lifecycle

    Arch-->>App: InitializeAsync completed
    deactivate Arch

    App->>Arch: WaitUntilReadyAsync()
    Arch->>Lifecycle: WaitUntilReadyAsync()
    Lifecycle-->>Arch: completed Task (already Ready)
    Arch-->>App: return
Loading

Class diagram for modular Architecture coordinator and managers

classDiagram
    direction LR

    class IArchitecture {
    <<interface>>
    +ArchitecturePhase CurrentPhase
    +IArchitectureContext Context
    +bool IsReady
    +void Initialize()
    +Task InitializeAsync()
    +ValueTask DestroyAsync()
    +void Destroy()
    +TSystem RegisterSystem~TSystem~(TSystem system)
    +void RegisterSystem~T~(Action~T~ onCreated)
    +TModel RegisterModel~TModel~(TModel model)
    +void RegisterModel~T~(Action~T~ onCreated)
    +TUtility RegisterUtility~TUtility~(TUtility utility)
    +void RegisterUtility~T~(Action~T~ onCreated)
    +IArchitectureModule InstallModule(IArchitectureModule module)
    +IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
    +Task WaitUntilReadyAsync()
    +event PhaseChanged(ArchitecturePhase phase)
    }

    class Architecture {
    -IArchitectureConfiguration Configuration
    -IEnvironment Environment
    -IArchitectureServices Services
    -ILogger _logger
    -IArchitectureContext _context
    -ArchitectureLifecycle _lifecycle
    -ArchitectureComponentRegistry _componentRegistry
    -ArchitectureModules _modules
    +ArchitecturePhase CurrentPhase
    +IArchitectureContext Context
    +bool IsReady
    +Action~IServiceCollection~ Configurator
    +event PhaseChanged(ArchitecturePhase phase)
    +Architecture(IArchitectureConfiguration configuration, IEnvironment environment, IArchitectureServices services, IArchitectureContext context)
    +IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
    +void RegisterMediatorBehavior~TBehavior~()
    +IArchitectureModule InstallModule(IArchitectureModule module)
    +TSystem RegisterSystem~TSystem~(TSystem system)
    +void RegisterSystem~T~(Action~T~ onCreated)
    +TModel RegisterModel~TModel~(TModel model)
    +void RegisterModel~T~(Action~T~ onCreated)
    +TUtility RegisterUtility~TUtility~(TUtility utility)
    +void RegisterUtility~T~(Action~T~ onCreated)
    +void Initialize()
    +Task InitializeAsync()
    +Task WaitUntilReadyAsync()
    +ValueTask DestroyAsync()
    +void Destroy()
    #void OnInitialize()
    }

    class ArchitectureLifecycle {
    -IArchitecture _architecture
    -IArchitectureConfiguration _configuration
    -IArchitectureServices _services
    -ILogger _logger
    -TaskCompletionSource _readyTcs
    -HashSet~IInitializable~ _pendingInitializableSet
    -List~IInitializable~ _pendingInitializableList
    -HashSet~object~ _disposableSet
    -List~object~ _disposables
    -List~IArchitectureLifecycleHook~ _lifecycleHooks
    -bool _initialized
    +ArchitecturePhase CurrentPhase
    +bool IsReady
    +bool IsInitialized
    +event PhaseChanged(ArchitecturePhase phase)
    +ArchitectureLifecycle(IArchitecture architecture, IArchitectureConfiguration configuration, IArchitectureServices services, ILogger logger)
    +IArchitectureLifecycleHook RegisterLifecycleHook(IArchitectureLifecycleHook hook)
    +void RegisterLifecycleComponent~T~(T component)
    +void EnterPhase(ArchitecturePhase next)
    +Task InitializeAllComponentsAsync(bool asyncMode)
    +ValueTask DestroyAsync()
    +void Destroy()
    +void MarkAsReady()
    +void MarkAsFailed(Exception exception)
    +Task WaitUntilReadyAsync()
    }

    class ArchitectureComponentRegistry {
    -IArchitecture architecture
    -IArchitectureConfiguration configuration
    -IArchitectureServices services
    -ArchitectureLifecycle lifecycle
    -ILogger logger
    +ArchitectureComponentRegistry(IArchitecture architecture, IArchitectureConfiguration configuration, IArchitectureServices services, ArchitectureLifecycle lifecycle, ILogger logger)
    +TSystem RegisterSystem~TSystem~(TSystem system)
    +void RegisterSystem~T~(Action~T~ onCreated)
    +TModel RegisterModel~TModel~(TModel model)
    +void RegisterModel~T~(Action~T~ onCreated)
    +TUtility RegisterUtility~TUtility~(TUtility utility)
    +void RegisterUtility~T~(Action~T~ onCreated)
    }

    class ArchitectureModules {
    -IArchitecture architecture
    -IArchitectureServices services
    -ILogger logger
    +ArchitectureModules(IArchitecture architecture, IArchitectureServices services, ILogger logger)
    +void RegisterMediatorBehavior~TBehavior~()
    +IArchitectureModule InstallModule(IArchitectureModule module)
    }

    class IArchitectureLifecycleHook {
    <<interface>>
    +void OnPhase(ArchitecturePhase phase, IArchitecture architecture)
    }

    class IArchitecturePhaseListener {
    <<interface>>
    +void OnArchitecturePhase(ArchitecturePhase phase)
    }

    class IArchitectureModule {
    <<interface>>
    +void Install(IArchitecture architecture)
    }

    class IArchitectureServices {
    <<interface>>
    +IIocContainer Container
    +IArchitectureModuleManager ModuleManager
    }

    class IIocContainer {
    <<interface>>
    +void RegisterPlurality~T~(T instance)
    +void RegisterFactory~T~(Func~IServiceProvider,T~ factory)
    +IEnumerable~T~ GetAll~T~()
    +bool Contains~T~()
    +void RegisterMediatorBehavior~TBehavior~()
    +void ExecuteServicesHook(Action~IServiceCollection~ configurator)
    +void Freeze()
    +void Clear()
    }

    class IArchitectureModuleManager {
    <<interface>>
    +void RegisterBuiltInModules(IIocContainer container)
    +Task InitializeAllAsync(bool asyncMode)
    +ValueTask DestroyAllAsync()
    }

    class IModel {
    <<interface>>
    +void SetContext(IArchitectureContext context)
    }

    class ISystem {
    <<interface>>
    +void SetContext(IArchitectureContext context)
    }

    class IUtility {
    <<interface>>
    }

    class IContextUtility {
    <<interface>>
    +void SetContext(IArchitectureContext context)
    }

    class IInitializable {
    <<interface>>
    +void Initialize()
    }

    class IAsyncInitializable {
    <<interface>>
    +Task InitializeAsync()
    }

    class IDestroyable {
    <<interface>>
    +void Destroy()
    }

    class IAsyncDestroyable {
    <<interface>>
    +ValueTask DestroyAsync()
    }

    IArchitecture <|.. Architecture

    Architecture --> ArchitectureLifecycle : composes
    Architecture --> ArchitectureComponentRegistry : composes
    Architecture --> ArchitectureModules : composes
    Architecture --> IArchitectureServices : uses
    Architecture --> IEnvironment : uses

    ArchitectureLifecycle --> IArchitecture : coordinates
    ArchitectureLifecycle --> IArchitectureServices : uses
    ArchitectureLifecycle --> IArchitectureLifecycleHook : manages
    ArchitectureLifecycle --> IArchitecturePhaseListener : notifies
    ArchitectureLifecycle --> IInitializable : manages
    ArchitectureLifecycle --> IAsyncInitializable : manages
    ArchitectureLifecycle --> IDestroyable : manages
    ArchitectureLifecycle --> IAsyncDestroyable : manages

    ArchitectureComponentRegistry --> IArchitecture : uses
    ArchitectureComponentRegistry --> IArchitectureServices : uses
    ArchitectureComponentRegistry --> ArchitectureLifecycle : uses
    ArchitectureComponentRegistry --> IModel : registers
    ArchitectureComponentRegistry --> ISystem : registers
    ArchitectureComponentRegistry --> IUtility : registers
    ArchitectureComponentRegistry --> IContextUtility : registers

    ArchitectureModules --> IArchitecture : uses
    ArchitectureModules --> IArchitectureServices : uses
    ArchitectureModules --> IArchitectureModule : installs

    IArchitectureServices --> IIocContainer : has
    IArchitectureServices --> IArchitectureModuleManager : has

    IContextUtility --|> IUtility
    IAsyncInitializable --|> IInitializable
    IAsyncDestroyable --|> IDestroyable
Loading

File-Level Changes

Change Details Files
Refactor Architecture into a coordinator that delegates lifecycle, component registration, and module management to dedicated manager classes, with safer construction-time initialization and a new PhaseChanged event.
  • Replaced the primary Architecture class constructor with one that eagerly initializes configuration, environment, services, logger, and three new manager instances: ArchitectureLifecycle, ArchitectureComponentRegistry, and ArchitectureModules.
  • Moved lifecycle-specific responsibilities (phase tracking, validation, phase notifications, component init/destroy queues, ready TaskCompletionSource) out of Architecture into the new ArchitectureLifecycle class.
  • Moved component registration logic for systems, models, and utilities (including context wiring, lifecycle registration, and factory-based DI registration) into ArchitectureComponentRegistry.
  • Moved mediator behavior registration and module installation logic into ArchitectureModules and updated Architecture to delegate the corresponding public methods.
  • Replaced direct field/state usage in Architecture (e.g., CurrentPhase, IsReady, WaitUntilReadyAsync, Destroy/DestroyAsync, mediator behavior registration, module installation, and component registration APIs) with calls into the new manager classes, preserving method signatures for backward compatibility.
  • Removed null-forgiving usages (e.g., logger/context fields) by fully initializing dependencies in the Architecture constructor and making logger/context fields readonly (where possible).
  • Replaced inline failed-initialization handling with ArchitectureLifecycle.MarkAsFailed and readiness signaling with ArchitectureLifecycle.MarkAsReady.
GFramework.Core/Architectures/Architecture.cs
GFramework.Core/Architectures/ArchitectureLifecycle.cs
GFramework.Core/Architectures/ArchitectureComponentRegistry.cs
GFramework.Core/Architectures/ArchitectureModules.cs
Introduce ArchitectureLifecycle as a dedicated lifecycle manager for phases, component initialization/destruction, and readiness tracking.
  • Implemented ArchitectureLifecycle to own ArchitecturePhase state, readiness flags, lifecycle hooks, and phase-aware notifications, using IArchitectureServices.Container to resolve IArchitecturePhaseListener instances.
  • Implemented validation of phase transitions honoring ArchitectureConfiguration.ArchitectureProperties.StrictPhaseValidation and allowing ArchitecturePhase.FailedInitialization from any phase.
  • Implemented component lifecycle registration that tracks IInitializable components for staged initialization and tracks components implementing IDestroyable or IAsyncDestroyable for reverse-order destruction.
  • Implemented InitializeAllComponentsAsync to group pending components by type (IContextUtility, IModel, ISystem), enter Before*/After* phases for utilities/models/systems, and invoke Initialize/InitializeAsync as appropriate.
  • Implemented DestroyAsync/Destroy to guard against double-destruction, set Destroying/Destroyed phases, asynchronously destroy all tracked disposables, destroy service modules, and clear the container.
  • Implemented readiness APIs (MarkAsReady, MarkAsFailed, WaitUntilReadyAsync) backed by a TaskCompletionSource that interacts with the new PhaseChanged event.
GFramework.Core/Architectures/ArchitectureLifecycle.cs
Introduce ArchitectureComponentRegistry to encapsulate and validate registration of systems, models, and utilities.
  • Implemented registration methods for systems, models, and utilities that validate registration against lifecycle phase and configuration (AllowLateRegistration), set component contexts, register components into the IoC container, and register them with ArchitectureLifecycle for init/destroy.
  • Implemented factory-based registration for system/model/utility types using ActivatorUtilities.CreateInstance, invoking optional user-supplied onCreated callbacks after core wiring.
  • Used type-safe helpers (e.g., IfType) to only apply context/lifecycle wiring to utilities that require a context.
GFramework.Core/Architectures/ArchitectureComponentRegistry.cs
Introduce ArchitectureModules to encapsulate module installation and mediator behavior registration.
  • Implemented RegisterMediatorBehavior that logs registration and delegates to services.Container.RegisterMediatorBehavior.
  • Implemented InstallModule to log module installation, call module.Install(architecture), and return the module instance.
  • Updated Architecture to delegate its public RegisterMediatorBehavior and InstallModule APIs to ArchitectureModules.
GFramework.Core/Architectures/ArchitectureModules.cs
GFramework.Core/Architectures/Architecture.cs
Update tests to use the new PhaseChanged event rather than overriding phase transitions directly.
  • Modified TestArchitectureBase to subscribe to the Architecture.PhaseChanged event inside OnInitialize and append phases to PhaseHistory, instead of overriding EnterPhase.
  • Ensured InitCalled flag and post-registration hook behavior remain intact for tests.
GFramework.Core.Tests/Architectures/TestArchitectureBase.cs
Revise and shrink the Architecture core documentation to match the new modular design and lifecycle semantics, and add an internal-structure section to the core index docs.
  • Rewrote docs/zh-CN/core/architecture.md from a large API-heavy usage guide into a more focused architectural overview explaining goals, core components, class diagram, lifecycle phases, initialization and destruction flows, and the new manager-based design.
  • Documented that Architecture now composes ArchitectureLifecycle, ArchitectureComponentRegistry, and ArchitectureModules and that managers are created in the constructor for safety and immediate availability.
  • Added documentation for the PhaseChanged event and examples showing how to subscribe to lifecycle changes and implement IArchitectureLifecycleHook.
  • Updated docs/zh-CN/core/index.md to describe the 11-phase lifecycle including FailedInitialization, the new modular structure of Architecture (v1.1.0+), and updated initialization flow diagrams reflecting construction-time manager initialization.
  • Added a versioned changelog (v1.1.0) and marked key behavioral changes as backward compatible at the public API level.
docs/zh-CN/core/architecture.md
docs/zh-CN/core/index.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好——我发现了两个问题,并留下了一些整体层面的反馈:

  • ArchitectureLifecycle.DestroyAsync 中,你现在在 CurrentPhase == ArchitecturePhase.None 时会提前返回;这可能会跳过对那些在初始化之前就已注册并添加到 _disposables 中的组件的释放,而这些组件之前是会被清理掉的——建议在这种状态下仍然执行释放路径(或者禁止注册),以避免产生泄漏。
  • 新增的 ArchitectureLifecycle 中的 RegisterLifecycleComponent<T> 并没有用到它的泛型类型参数,而且只对若干接口类型进行操作;你可以将方法签名简化为接收 object(或特定的生命周期接口),以减少不必要的泛型噪音。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- In `ArchitectureLifecycle.DestroyAsync` you now return early when `CurrentPhase == ArchitecturePhase.None`; this can skip disposing components that were registered before initialization and added to `_disposables`, which previously would have been cleaned up—consider still running the disposal path (or preventing registration) in this state to avoid leaks.
- The new `RegisterLifecycleComponent<T>` in `ArchitectureLifecycle` doesn’t use its generic type parameter and only operates on interface types; you could simplify the signature to accept `object` (or specific lifecycle interfaces) to reduce unnecessary generic noise.

## Individual Comments

### Comment 1
<location path="GFramework.Core/Architectures/ArchitectureLifecycle.cs" line_range="62-71" />
<code_context>
+    public void RegisterLifecycleComponent<T>(T component)
</code_context>
<issue_to_address>
**suggestion:** Consider removing the generic type parameter from RegisterLifecycleComponent since it is unused.

Since `T` isn’t used and the method relies on the runtime type of `component`, you can change the signature to something like `public void RegisterLifecycleComponent(object component)` (or a relevant interface). This avoids unnecessary generic instantiation, reduces caller noise, and keeps the API surface smaller.

Suggested implementation:

```csharp
    /// <summary>
    ///     统一的组件生命周期注册逻辑
    /// </summary>
    /// <param name="component">要注册的组件</param>
    public void RegisterLifecycleComponent(object component)

```

1. Update all call sites of `RegisterLifecycleComponent` to remove the generic type argument, e.g. change `RegisterLifecycleComponent<MyType>(myInstance)` to `RegisterLifecycleComponent(myInstance)`.
2. If there are any references using method group syntax or reflection that assume a generic signature (e.g. `MethodInfo` lookups), adjust them to use the non-generic `RegisterLifecycleComponent(object component)` signature.
</issue_to_address>

### Comment 2
<location path="docs/zh-CN/core/architecture.md" line_range="219-221" />
<code_context>
+   │   ├─> 优先调用 IAsyncDestroyable.DestroyAsync()
+   │   └─> 否则调用 IDestroyable.Destroy()
+   ├─> 销毁服务模块
+   ├─> 清空 IOC 容器
+   └─> 进入 Destroyed 阶段
+```
</code_context>
<issue_to_address>
**suggestion (typo):** “IOC 容器”的大小写与文中其他“IoC 容器”的写法不一致。

建议将此处改为 “IoC 容器”,与前文保持一致,避免被理解为不同概念。

```suggestion
   ├─> 销毁服务模块
   ├─> 清空 IoC 容器
   └─> 进入 Destroyed 阶段
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎帮忙分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • In ArchitectureLifecycle.DestroyAsync you now return early when CurrentPhase == ArchitecturePhase.None; this can skip disposing components that were registered before initialization and added to _disposables, which previously would have been cleaned up—consider still running the disposal path (or preventing registration) in this state to avoid leaks.
  • The new RegisterLifecycleComponent<T> in ArchitectureLifecycle doesn’t use its generic type parameter and only operates on interface types; you could simplify the signature to accept object (or specific lifecycle interfaces) to reduce unnecessary generic noise.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ArchitectureLifecycle.DestroyAsync` you now return early when `CurrentPhase == ArchitecturePhase.None`; this can skip disposing components that were registered before initialization and added to `_disposables`, which previously would have been cleaned up—consider still running the disposal path (or preventing registration) in this state to avoid leaks.
- The new `RegisterLifecycleComponent<T>` in `ArchitectureLifecycle` doesn’t use its generic type parameter and only operates on interface types; you could simplify the signature to accept `object` (or specific lifecycle interfaces) to reduce unnecessary generic noise.

## Individual Comments

### Comment 1
<location path="GFramework.Core/Architectures/ArchitectureLifecycle.cs" line_range="62-71" />
<code_context>
+    public void RegisterLifecycleComponent<T>(T component)
</code_context>
<issue_to_address>
**suggestion:** Consider removing the generic type parameter from RegisterLifecycleComponent since it is unused.

Since `T` isn’t used and the method relies on the runtime type of `component`, you can change the signature to something like `public void RegisterLifecycleComponent(object component)` (or a relevant interface). This avoids unnecessary generic instantiation, reduces caller noise, and keeps the API surface smaller.

Suggested implementation:

```csharp
    /// <summary>
    ///     统一的组件生命周期注册逻辑
    /// </summary>
    /// <param name="component">要注册的组件</param>
    public void RegisterLifecycleComponent(object component)

```

1. Update all call sites of `RegisterLifecycleComponent` to remove the generic type argument, e.g. change `RegisterLifecycleComponent<MyType>(myInstance)` to `RegisterLifecycleComponent(myInstance)`.
2. If there are any references using method group syntax or reflection that assume a generic signature (e.g. `MethodInfo` lookups), adjust them to use the non-generic `RegisterLifecycleComponent(object component)` signature.
</issue_to_address>

### Comment 2
<location path="docs/zh-CN/core/architecture.md" line_range="219-221" />
<code_context>
+   │   ├─> 优先调用 IAsyncDestroyable.DestroyAsync()
+   │   └─> 否则调用 IDestroyable.Destroy()
+   ├─> 销毁服务模块
+   ├─> 清空 IOC 容器
+   └─> 进入 Destroyed 阶段
+```
</code_context>
<issue_to_address>
**suggestion (typo):** “IOC 容器”的大小写与文中其他“IoC 容器”的写法不一致。

建议将此处改为 “IoC 容器”,与前文保持一致,避免被理解为不同概念。

```suggestion
   ├─> 销毁服务模块
   ├─> 清空 IoC 容器
   └─> 进入 Destroyed 阶段
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread GFramework.Core/Architectures/ArchitectureLifecycle.cs Outdated
Comment thread docs/zh-CN/core/architecture.md
- 将文档中的"IOC"统一更正为"IoC"格式
- 重构ArchitectureLifecycle类构造函数使用主构造函数语法
- 移除私有字段前缀下划线,直接使用参数名称
- 修复配置访问权限问题,移除字段访问前缀下划线
- 调整组件注册方法泛型约束,提升类型安全
- 优化日志记录器访问方式,移除字段访问前缀下划线
- 重构销毁逻辑,分离组件清理和服务模块销毁流程
- 提取清理组件逻辑到独立方法,提升代码可读性
- 更新阶段转换和钩子通知中的对象引用方式
@GeWuYou GeWuYou merged commit 27858df into main Mar 17, 2026
8 checks passed
@GeWuYou GeWuYou deleted the refactor/architecture-modular-safety branch March 17, 2026 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant