# Single Context Priority 追踪 ## 2026-05-07 ### 阶段:启动并收敛实现方向(SINGLE-CONTEXT-PRIORITY-RP-001) - 依据用户补充的运行时心智模型,确认当前 `Architecture` 更接近框架实例,`IArchitectureContext` 更接近功能入口,而不是需要并存运行的独立宿主 - 启动阶段已按仓库规则读取 `AGENTS.md`、`.ai/environment/tools.ai.yaml`、`ai-plan/public/README.md`,并在 `main` 上执行 `git pull --ff-only origin main` 后创建 `refactor/single-context-priority` - 本轮实现决策: - `GameContext` 维持兼容 API,但内部收敛为单活动上下文模型;允许多个类型键指向同一上下文实例,不允许并存多个不同上下文实例 - `MicrosoftDiContainer` 先做低风险修复:统一预冻结 `Get()` / `Get(Type)` 的实例可见性规则,并把 CQRS 注册服务解析改为复用同一条实例收集路径 - 若 `Contains()` 的预冻结语义仍保持“是否已有注册”,则通过 XML 文档和测试显式记录,而不是隐含为“可立即解析” - 本轮委托记录: - explorer `Noether`:梳理 `GameContext` 单活动上下文收敛的兼容风险、测试缺口和必须保留的 API 面 - explorer `Boole`:梳理 `MicrosoftDiContainer` 预冻结查询、`Contains()`、CQRS 注册依赖点的语义分叉 ### 阶段:实现与验证完成(SINGLE-CONTEXT-PRIORITY-RP-001) - 实现摘要: - `GameContext` 新增单活动上下文约束,`GetFirstArchitectureContext()` 改为显式返回当前活动上下文,不再依赖并发字典枚举顺序 - `GameContext.GetByType(Type)`、`Get()`、`TryGet()` 增加对当前活动上下文的兼容匹配,保留按架构类型别名回查能力 - `MicrosoftDiContainer.Get()` / `Get(Type)` 的预冻结实例查询改为复用 `CollectRegisteredImplementationInstances(...)` - `ResolveCqrsRegistrationService()` 改为复用同一条注册阶段实例可见性路径,并把失败信息收敛为更明确的契约提示 - `IIocContainer` XML 文档与 `docs/zh-CN/core/context.md`、`docs/zh-CN/core/rule.md`、`docs/zh-CN/source-generators/context-aware-generator.md` 已同步到“当前活动上下文 / 预冻结查询”语义 - 测试与验证: - `python3 scripts/license-header.py --check` 通过 - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~GameContextTests|FullyQualifiedName~ContextProviderTests|FullyQualifiedName~ContextAwareTests|FullyQualifiedName~MicrosoftDiContainerTests|FullyQualifiedName~IocContainerLifetimeTests|FullyQualifiedName~ArchitectureInitializationPipelineTests"` 通过,`92/92` passed - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` 通过,`0 warning / 0 error` ### 阶段:销毁闭环与文档收口完成(SINGLE-CONTEXT-PRIORITY-RP-002) - 实现摘要: - `Architecture.DestroyAsync()` 新增 `finally` 解绑,确保销毁完成后自动从 `GameContext` 移除当前架构类型绑定 - `ArchitectureLifecycleBehaviorTests` 新增销毁解绑、失败初始化后解绑、以及销毁后新 `ContextAwareBase` 实例不再回退到过期上下文的回归测试 - `docs/zh-CN/source-generators/context-get-generator.md` 已把“多架构场景”改写为“自定义上下文来源”,收口对全局多架构并存的暗示 - 测试与验证: - `python3 scripts/license-header.py --check` 通过 - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureLifecycleBehaviorTests|FullyQualifiedName~SyncArchitectureTests|FullyQualifiedName~AsyncArchitectureTests|FullyQualifiedName~ArchitectureInitializationPipelineTests|FullyQualifiedName~ContextAwareTests"` 通过,`32/32` passed - 首次并发执行 `dotnet test` 与 `dotnet build` 时出现 `bin/Release` 文件占用导致的 MSBuild copy 冲突;按仓库规则改为单独重跑直接命令后结果通过 - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` 单独重跑通过,`0 warning / 0 error` ### 当前下一步 1. 若后续要进一步彻底移除全局回退,可单独评估 `GameContext` 公开别名字典的收口策略与生成器默认 provider 的进一步简化空间 ### 阶段:PR review 跟进修复(SINGLE-CONTEXT-PRIORITY-RP-003) - Review 来源: - PR `#332`(`refactor/single-context-priority`)上的 CodeRabbit unresolved outside-diff / nitpick comments - PR `#332` 上 Greptile 的两个 latest-head open threads - 本轮确认并接受的结论: - `Architecture.Destroy()` 与 `DestroyAsync()` 存在语义漂移,前者缺少 `GameContext.Unbind(GetType())` 清理,仍然会泄漏过期全局回退入口 - `GameContext` 仅靠 `ConcurrentDictionary` + `_currentArchitectureContext` 的分离更新无法保证组合状态一致;`Bind` / `Unbind` / `Clear` 与读取路径需要统一同步边界 - `GameContextProvider.GetContext()`、`ContextAwareBase.GetContext()`、`Architecture.DestroyAsync()` 等处的 XML 文档仍未完全反映最新生命周期语义 - `RegisterCqrsHandlersFromAssemblies_Should_Resolve_Registration_Service_When_Registered_As_Instance` 需要从“仅不抛异常”加强为“确实注册了 handler” - 本轮实现摘要: - 为 `GameContext` 新增统一临界区,保证别名字典与当前活动上下文指针的状态切换一致 - 为 `Architecture.Destroy()` 增加 `finally` 解绑,和异步销毁路径对齐 - 补充 `GameContextProvider`、`ContextAwareBase`、`Architecture`、`GameContext` 的 XML 文档说明 - 新增同步 `Destroy()` 解绑回归测试,并加强 CQRS 注册断言 - 验证与环境备注: - `python3 scripts/license-header.py --check` 通过 - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~GameContextTests|FullyQualifiedName~ContextProviderTests|FullyQualifiedName~ContextAwareTests|FullyQualifiedName~ArchitectureLifecycleBehaviorTests|FullyQualifiedName~MicrosoftDiContainerTests"` 通过,`87/87` passed - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` 通过,`0 warning / 0 error` - 中途尝试把 `dotnet test` 与 `dotnet build` 并行执行时再次触发 `GFramework.Core.pdb` 占用重试;按仓库规则改为串行直跑后结果稳定通过 - `System.Threading.Lock` 在 `net8.0` 目标下不可用,因此最终采用 `#if NET9_0_OR_GREATER` 条件锁声明,同时保留 `net8.0` 的 `object` 锁兼容实现