diff --git a/GFramework.Core/Architectures/ArchitectureLifecycle.cs b/GFramework.Core/Architectures/ArchitectureLifecycle.cs index d503f68c..c0fed21f 100644 --- a/GFramework.Core/Architectures/ArchitectureLifecycle.cs +++ b/GFramework.Core/Architectures/ArchitectureLifecycle.cs @@ -145,69 +145,34 @@ internal sealed class ArchitectureLifecycle( { logger.Info($"Initializing {_pendingInitializableList.Count} components"); - // 按类型分组初始化(保持原有的阶段划分) - var utilities = _pendingInitializableList.OfType().ToList(); - var models = _pendingInitializableList.OfType().ToList(); - var systems = _pendingInitializableList.OfType().ToList(); + var initializationPlan = CreateInitializationPlan(); - // 1. 工具初始化阶段 - EnterPhase(ArchitecturePhase.BeforeUtilityInit); + await InitializePhaseComponentsAsync( + initializationPlan.Utilities, + ArchitecturePhase.BeforeUtilityInit, + ArchitecturePhase.AfterUtilityInit, + "context utilities", + "utility", + asyncMode) + .ConfigureAwait(false); + await InitializePhaseComponentsAsync( + initializationPlan.Models, + ArchitecturePhase.BeforeModelInit, + ArchitecturePhase.AfterModelInit, + "models", + "model", + asyncMode) + .ConfigureAwait(false); + await InitializePhaseComponentsAsync( + initializationPlan.Systems, + ArchitecturePhase.BeforeSystemInit, + ArchitecturePhase.AfterSystemInit, + "systems", + "system", + asyncMode) + .ConfigureAwait(false); - if (utilities.Count != 0) - { - logger.Info($"Initializing {utilities.Count} context utilities"); - - foreach (var utility in utilities) - { - logger.Debug($"Initializing utility: {utility.GetType().Name}"); - await InitializeComponentAsync(utility, asyncMode).ConfigureAwait(false); - } - - logger.Info("All context utilities initialized"); - } - - EnterPhase(ArchitecturePhase.AfterUtilityInit); - - // 2. 模型初始化阶段 - EnterPhase(ArchitecturePhase.BeforeModelInit); - - if (models.Count != 0) - { - logger.Info($"Initializing {models.Count} models"); - - foreach (var model in models) - { - logger.Debug($"Initializing model: {model.GetType().Name}"); - await InitializeComponentAsync(model, asyncMode).ConfigureAwait(false); - } - - logger.Info("All models initialized"); - } - - EnterPhase(ArchitecturePhase.AfterModelInit); - - // 3. 系统初始化阶段 - EnterPhase(ArchitecturePhase.BeforeSystemInit); - - if (systems.Count != 0) - { - logger.Info($"Initializing {systems.Count} systems"); - - foreach (var system in systems) - { - logger.Debug($"Initializing system: {system.GetType().Name}"); - await InitializeComponentAsync(system, asyncMode).ConfigureAwait(false); - } - - logger.Info("All systems initialized"); - } - - EnterPhase(ArchitecturePhase.AfterSystemInit); - - _pendingInitializableList.Clear(); - _pendingInitializableSet.Clear(); - _initialized = true; - logger.Info("All components initialized"); + MarkInitializationCompleted(); } /// @@ -223,6 +188,67 @@ internal sealed class ArchitectureLifecycle( component.Initialize(); } + /// + /// 按架构既有阶段语义把待初始化组件拆分为 utility、model 和 system 三个批次。 + /// 这样可以在压缩主流程复杂度的同时,继续复用注册顺序和接口类型决定的初始化分层。 + /// + /// 当前待初始化组件的阶段化批次。 + private InitializationPlan CreateInitializationPlan() + { + return new InitializationPlan( + _pendingInitializableList.OfType().ToList(), + _pendingInitializableList.OfType().ToList(), + _pendingInitializableList.OfType().ToList()); + } + + /// + /// 执行单个生命周期阶段的批量初始化,并统一维护阶段切换、日志输出和异步初始化策略。 + /// + /// 当前阶段要初始化的组件类型。 + /// 当前阶段的组件列表。 + /// 阶段开始前要进入的生命周期状态。 + /// 阶段结束后要进入的生命周期状态。 + /// 用于批量日志的组件组名称。 + /// 用于单个组件日志的组件角色名称。 + /// 是否允许优先走异步初始化契约。 + private async Task InitializePhaseComponentsAsync( + IReadOnlyList components, + ArchitecturePhase beforePhase, + ArchitecturePhase afterPhase, + string componentGroupName, + string componentLogName, + bool asyncMode) + where TComponent : class, IInitializable + { + EnterPhase(beforePhase); + + if (components.Count != 0) + { + logger.Info($"Initializing {components.Count} {componentGroupName}"); + + foreach (var component in components) + { + logger.Debug($"Initializing {componentLogName}: {component.GetType().Name}"); + await InitializeComponentAsync(component, asyncMode).ConfigureAwait(false); + } + + logger.Info($"All {componentGroupName} initialized"); + } + + EnterPhase(afterPhase); + } + + /// + /// 在所有阶段初始化完成后清理挂起列表,并把生命周期状态切换到“已初始化”。 + /// + private void MarkInitializationCompleted() + { + _pendingInitializableList.Clear(); + _pendingInitializableSet.Clear(); + _initialized = true; + logger.Info("All components initialized"); + } + /// /// 立即初始化在常规初始化批次完成后新增的组件。 /// 当启用 AllowLateRegistration 时,生命周期层需要和注册层保持一致, @@ -258,6 +284,17 @@ internal sealed class ArchitectureLifecycle( #endregion + /// + /// 保存一次完整初始化流程所需的三个阶段批次。 + /// + /// Utility 初始化批次。 + /// Model 初始化批次。 + /// System 初始化批次。 + private readonly record struct InitializationPlan( + IReadOnlyList Utilities, + IReadOnlyList Models, + IReadOnlyList Systems); + #region Ready State /// diff --git a/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md b/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md index 3a2b85dd..6a8e1f4d 100644 --- a/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md +++ b/ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md @@ -7,12 +7,12 @@ ## 当前恢复点 -- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-002` -- 当前阶段:`Phase 2` +- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-003` +- 当前阶段:`Phase 3` - 当前焦点: - - 已完成 `GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs` 的 `MA0051` 长方法拆分,保持 generated registry、fallback 与缓存语义不变 - - 已确认 `GFramework.Cqrs` 定向构建恢复为 `0 Warning(s)`,该 warning slice 已不再是当前主题的阻塞项 - - 下一轮若继续推进,优先从 `GFramework.Core` 剩余的 `MA0051`、`MA0046` 或低风险 `MA0016` 中只选一个切入点 + - 已完成 `GFramework.Core/Architectures/ArchitectureLifecycle.cs` 的 `MA0051` 长方法拆分,保持阶段推进、日志文本和 late registration 语义不变 + - 已确认 `GFramework.Core` 定向 `warnings-only` 构建从 `30 Warning(s)` 收敛到 `29 Warning(s)`,`ArchitectureLifecycle` 已不再出现在剩余 `MA0051` 热点中 + - 下一轮若继续推进,优先从 `PauseStackManager`、`CoroutineScheduler` 或 `Store` 的剩余 `MA0051` 中只选一个切入点 ## 当前状态摘要 @@ -26,6 +26,7 @@ - 当前主题仍是 active topic,因为剩余结构性 warning 是否继续推进尚未决策 - `RP-001` 的详细实现历史、测试记录和 warning 热点清单已归档到主题内 `archive/` - `RP-002` 已在不改公共契约的前提下完成 `CqrsHandlerRegistrar` 结构拆分,并通过定向 build/test 验证 +- `RP-003` 已在不改生命周期契约的前提下完成 `ArchitectureLifecycle` 初始化主流程拆分,并通过定向 build/test 验证 - 当前工作树分支 `fix/analyzer-warning-reduction-batch` 已在 `ai-plan/public/README.md` 建立 topic 映射 ## 当前风险 @@ -48,11 +49,14 @@ - `RP-002` 的定向验证结果: - `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release --no-restore -p:TargetFramework=net8.0 -p:UseSharedCompilation=false -p:RestoreFallbackFolders=` - `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --filter FullyQualifiedName~CqrsHandlerRegistrarTests -p:RestoreFallbackFolders=` +- `RP-003` 的定向验证结果: + - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders= -nologo -clp:Summary;WarningsOnly` + - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter FullyQualifiedName~ArchitectureLifecycleBehaviorTests -p:RestoreFallbackFolders=` - active 跟踪文件只保留当前恢复点、活跃事实、风险与下一步,不再重复保存已完成阶段的长篇历史 ## 下一步 1. 若要继续该主题,先读 active tracking,再按需展开历史归档中的 warning 热点与验证记录 -2. 优先在 `GFramework.Core/Architectures/ArchitectureLifecycle.cs`、`GFramework.Core/Coroutine/CoroutineScheduler.cs` 与 - `GFramework.Core/Pause/PauseStackManager.cs` 的 `MA0051` 中只选一个继续,不要在同一轮同时扩多个风险面 +2. 优先在 `GFramework.Core/Pause/PauseStackManager.cs`、`GFramework.Core/Coroutine/CoroutineScheduler.cs` 与 + `GFramework.Core/StateManagement/Store.cs` 的 `MA0051` 中只选一个继续,不要在同一轮同时扩多个风险面 3. 若本主题确认暂缓,可保持当前归档状态,不需要再恢复 `local-plan/` diff --git a/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md b/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md index d23aca6d..e879388b 100644 --- a/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md +++ b/ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md @@ -2,6 +2,26 @@ ## 2026-04-21 +### 阶段:Architecture 生命周期 `MA0051` 收口(RP-003) + +- 依据 active tracking 中“继续只选一个 `GFramework.Core` 结构性切入点”的约束,选定 + `GFramework.Core/Architectures/ArchitectureLifecycle.cs`,因为文件体量适中且已有 + `ArchitectureLifecycleBehaviorTests` 覆盖阶段流转、销毁顺序和 late registration 行为 +- 先用 `warnings-only` 定向构建确认 `ArchitectureLifecycle.InitializeAllComponentsAsync` 仍在报 + `MA0051`,随后把主流程拆成: + - `CreateInitializationPlan` + - `InitializePhaseComponentsAsync` + - `MarkInitializationCompleted` +- 保持原有阶段顺序 `Before* -> After*`、批量日志文本和异步初始化策略不变,只压缩主方法长度 +- 修正新增 `InitializationPlan` 记录类型的 XML `` 名称大小写,避免引入文档告警 +- 验证通过: + - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release -t:Rebuild --no-restore -p:UseSharedCompilation=false -p:TargetFramework=net8.0 -p:RestoreFallbackFolders= -nologo -clp:Summary;WarningsOnly` + - 结果:`29 Warning(s)`,`0 Error(s)`;`ArchitectureLifecycle.cs` 已不再出现在 warning 列表 + - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter FullyQualifiedName~ArchitectureLifecycleBehaviorTests -p:RestoreFallbackFolders=` + - 结果:`6 Passed`,`0 Failed` + +## 2026-04-21 + ### 阶段:CQRS `MA0051` 收口(RP-002) - 依据 active tracking 中“先只选一个结构性切入点”的约束,选定 `GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs`