Skip to content

Refactor/single context priority#332

Merged
GeWuYou merged 3 commits intomainfrom
refactor/single-context-priority
May 7, 2026
Merged

Refactor/single context priority#332
GeWuYou merged 3 commits intomainfrom
refactor/single-context-priority

Conversation

@GeWuYou
Copy link
Copy Markdown
Owner

@GeWuYou GeWuYou commented May 7, 2026

Summary by CodeRabbit

发布说明

  • 新功能

    • 引入单一活动上下文优先模型,增强全局上下文的兼容查找与并发安全。
  • Bug 修复

    • 确保架构销毁路径始终解除全局上下文绑定,防止回退泄露。
  • 文档

    • 明确 IoC 查询在冻结前的可见性语义与 Contains 行为;补充上下文感知和回退语义中文说明。
  • 测试

    • 增加架构生命周期、上下文绑定与预冻结 DI 可见性等回归测试覆盖。

GeWuYou added 2 commits May 7, 2026 08:58
- 收敛 GameContext 为单活动上下文模型并保留类型别名兼容查找

- 统一 MicrosoftDiContainer 预冻结实例读取路径并补充 CQRS 注册阶段提示

- 更新 Core 测试、上下文文档与 ai-plan 追踪记录
- 修复 Architecture 销毁后 GameContext 仍保留活动上下文的问题

- 补充生命周期回归测试并验证失败初始化后的解绑路径

- 收口生成器文档中的多架构表述并更新 ai-plan 追踪
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1ec3f42d-402c-4114-9a26-7381235768f1

📥 Commits

Reviewing files that changed from the base of the PR and between ff04a4f and ee8b6a4.

📒 Files selected for processing (8)
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContext.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core/Rule/ContextAwareBase.cs
  • ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md
  • ai-plan/public/single-context-priority/traces/single-context-priority-trace.md
✅ Files skipped from review due to trivial changes (1)
  • GFramework.Core/Architectures/GameContextProvider.cs
🚧 Files skipped from review as they are similar to previous changes (4)
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • ai-plan/public/single-context-priority/traces/single-context-priority-trace.md
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (C#)
  • GitHub Check: Code Quality & Security
  • GitHub Check: Build and Test
🧰 Additional context used
📓 Path-based instructions (8)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) in C#
XML documentation MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable, and explain intent, contract, and usage constraints instead of restating syntax
If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why abstraction exists, and when to use instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Do not rely on implicit imports. Declare every required using explicitly in C#
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C#
Use namespace pattern GFramework.{Module}.{Feature} with PascalCase segments in C#
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, Interfaces use I prefix, Parameters and locals use camelCase, Private fields use _camelCase
Use Allman braces style for C#
Keep using directives at the top of the file and sort them consistently in C#
Prefer one primary type per file unless surrounding project already uses different local pattern
Prefer explicit, readable code over clever shorthand in framework internals
M...

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*[!.]*

📄 CodeRabbit inference engine (AGENTS.md)

For files with shebang lines, keep shebang as first line and place license header immediately after it

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py,sh}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py,sh}: All generated or modified code MUST include clear and meaningful comments where required by documentation rules
Comments MUST NOT be trivial, redundant, or misleading. Prefer explaining why and when, not just what. Code should remain understandable without requiring external context
Avoid obvious comments such as // increment i

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{csproj,cs}

📄 CodeRabbit inference engine (AGENTS.md)

Framework runtime, abstractions, and meta-package projects MUST NOT reference *.SourceGenerators* projects or packages, and MUST NOT use source-generator attributes

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation. Do not use tabs

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}

📄 CodeRabbit inference engine (AGENTS.md)

Keep line length readable. Around 120 characters is preferred upper bound

Files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form

Files:

  • ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core/Architectures/GameContext.cs
🪛 LanguageTool
ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md

[uncategorized] ~20-~20: 您的意思是“"不"齐”?
Context: ...PR review 跟进中,Architecture.Destroy() 已补齐相同解绑语义,GameContext 也改为通过统一临界区维护别名字典与当...

(BU)

🔇 Additional comments (2)
GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs (1)

186-258: 新增销毁解绑回归测试覆盖到位。

四个新测试分别覆盖了正常销毁、FailedInitialization 后销毁、新建 ContextAwareBase 探针不再命中过期上下文、以及兼容的同步 Destroy() 入口的解绑路径,与 Architecture.DestroyAsync()try/finally 解绑语义和 GameContext 的单活动上下文模型相互印证;#pragma warning disable CS0618 也仅围绕 Destroy() 调用做了最小化作用域。

GFramework.Core/Architectures/GameContext.cs (1)

15-23: TOCTOU 竞态已通过 SyncRoot 收口,复合状态保持原子。

Bind/Unbind/Clear/Get* 现在统一在同一把锁内维护“别名字典 + _currentArchitectureContext”不变式:

  • Bind 在锁内先做活动上下文比对、再 TryAdd,最后通过 ??= 设置当前指针,任何分支抛出都不会留下半提交状态;
  • Unbind 在锁内连续完成 TryRemove → 引用比对 → HasAliasForContext 扫描 → 清空指针,杜绝了之前 TryRemoveAny() 之间被并发 Bind 插入的快照问题;
  • Clear 在锁内同时清空字典与指针。

#if NET9_0_OR_GREATER 选用 System.Threading.Lock 是正确的 C# 13 习惯用法;ConcurrentDictionary 保留也合理 —— 公共只读视图 ArchitectureReadOnlyDictionary 仍可在不持锁的情况下安全枚举。线程安全假设也按指南在锁声明处做了说明。

Also applies to: 43-61, 163-178, 184-191, 193-207


📝 Walkthrough

Walkthrough

本 PR 将 GameContext 从多上下文字典改为单一“当前活动上下文”模型,调整 MicrosoftDiContainer 在预冻结阶段的实例可见性与去重逻辑,并确保 Architecture.DestroyAsync 在销毁时始终从全局注册表解绑上下文;同时补充相关测试与文档说明。(约 34 字)

Changes

单一活动上下文语义重构及生命周期清理

Layer / File(s) Summary
接口文档补充
GFramework.Core.Abstractions/Ioc/IIocContainer.cs
Get<T>/Get(Type)/GetAll*/Contains<T>() 添加 XML remarks,说明在未调用 Freeze() 时这些查询只枚举已可见的实例绑定,不触发工厂或类型激活。
GameContext 核心重构(数据与同步)
GFramework.Core/Architectures/GameContext.cs
新增 _currentArchitectureContext 字段、SyncRoot 锁与 HasAliasForContext 帮助方法;将原并发字典模型扩展为“字典 + 活动指针”组合以维护一致性。
GameContext 核心重构(行为)
GFramework.Core/Architectures/GameContext.cs
Bind 增加非空校验并禁止在已有活动实例时激活不同实例;GetFirstArchitectureContext 改为返回活动上下文;GetByType/Get<T>/TryGet<T> 优先匹配活动上下文,回退到别名查找;Unbind/Clear 在移除别名时同步维护活动指针,仅在无其它别名引用时清除。
销毁生命周期清理
GFramework.Core/Architectures/Architecture.cs
DestroyAsync() 改为 try/finally,在 finally 中始终调用 GameContext.Unbind(GetType()),保证无论销毁是否抛出均解绑上下文;同步保持已弃用的同步 Destroy() 行为。
IoC 容器预冻结可见性改动
GFramework.Core/Ioc/MicrosoftDiContainer.cs
新增 CollectRegisteredImplementationInstancesBuildPreferredVisibleServiceTypesSelectPreferredVisibleServiceType 等实现,预冻结阶段过滤并去重实例(跳过 ImplementationFactory/ImplementationType),并调整 Get<T>/Get(Type)ResolveCqrsRegistrationService 在未冻结路径使用该收集管线。
文档与注释更新(行为说明)
GFramework.Core/Architectures/GameContextProvider.cs, GFramework.Core/Rule/ContextAwareBase.cs
扩充 XML 文档,明确 GetContext()/TryGetContext<T> 在缺省情况下回退到“当前活动上下文”的语义与边界(无额外同步或 provider 替换)。
测试覆盖验证
GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs, GFramework.Core.Tests/Architectures/ContextProviderTests.cs, GFramework.Core.Tests/Architectures/GameContextTests.cs, GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs, GFramework.Core.Tests/Rule/ContextAwareTests.cs
新增/调整测试以验证:销毁后全局解绑、初始化失败后解绑、活动上下文优先/别名回退、预冻结阶段的实例可见性与去重、Contains<T>() 的预冻结含义、以及 ContextAwareBase 的回退返回当前活动上下文。
中文文档澄清
docs/zh-CN/core/context.md, docs/zh-CN/core/rule.md, docs/zh-CN/source-generators/context-aware-generator.md, docs/zh-CN/source-generators/context-get-generator.md
补充/重述 ContextAwareBase 的回退语义为“当前活动上下文”,并记录 SetContextProvider 等自定义上下文来源的使用情形。
规划与追踪文档
ai-plan/public/README.md, ai-plan/public/single-context-priority/...
新增/更新 Single Context Priority 的跟踪与轨迹文档,记录实现决策、验证步骤与后续待办。

Sequence Diagram(s)

sequenceDiagram
    participant Architecture
    participant GameContext
    participant ContextAwareProbe
    Architecture->>GameContext: Bind(architectureType, context)
    GameContext-->>Architecture: record _currentArchitectureContext
    ContextAwareProbe->>GameContext: GetFirstArchitectureContext()/TryGet -> 返回活动上下文
    Architecture->>Architecture: DestroyAsync()
    Architecture->>GameContext: Unbind(GetType()) (in finally)
    GameContext-->>ContextAwareProbe: subsequent GetContext() 抛出/不可用
Loading
sequenceDiagram
    participant Registrar
    participant MicrosoftDiContainer
    participant ServiceProvider
    Registrar->>MicrosoftDiContainer: RegisterSingleton / RegisterPlurality / RegisterCqrsHandlers...
    MicrosoftDiContainer->>MicrosoftDiContainer: CollectRegisteredImplementationInstances (pre-freeze)
    MicrosoftDiContainer-->>Registrar: Get<T>() 返回收集并去重后的实例
    Registrar->>MicrosoftDiContainer: Freeze() -> 构建 _provider
    MicrosoftDiContainer->>ServiceProvider: Get<T>() (post-freeze) 使用内建 provider 解析
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • GeWuYou/GFramework#264:对中文文档(docs/zh-CN/core/context.md)存在相关更新,可能涉及相同语义澄清。
  • GeWuYou/GFramework#244:涉及 ContextAware/ContextAwareBase 的回退语义与生成器相关调整。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题「Refactor/single context priority」与 PR 的核心变更高度相关,准确反映了此次重构的主要目标——围绕「单一上下文优先」模型统一和改进 GameContext 和 MicrosoftDiContainer 的语义。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/single-context-priority

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2299 2299 0 0 0 0 1ms

Test Results

passed 2299 passed

Details

tests 2299 tests
clock 38.2s
tool nunit
build CI - Build & Test arrow-right build-and-test link #1072
pull-request Refactor/single context priority link #332

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2299 0 0 4.1s

build-and-test: Run #1072

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2299 2299 0 0 0 0 0 38.2s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 1 4.1s 4.1s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 1 2.3s 2.3s
Generates_Scene_Behavior_Boilerplate 1 1.9s 1.9s
CleanupDuringAcquire_Should_NotCauseRaceCondition 1 1.1s 1.1s
Append_ShouldNotBlock 1 1.0s 1.0s
Context_Caching_Should_Improve_Performance 1 777ms 777ms
PendingCount_ShouldReflectQueuedEntries 1 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 1 404ms 404ms
Cleanup_Should_RemoveUnusedLocks 1 401ms 401ms
Generates_Precise_Assembly_Type_Lookups_For_Inaccessible_External_Generic_Definitions_With_Visible_Type_Arguments 1 324ms 324ms

🎉 No failed tests in this run. | 🍂 No flaky tests in this run.

Github Test Reporter by CTRF 💚

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
⚠️ CSHARP dotnet-format yes 1 no 5.66s
✅ REPOSITORY gitleaks yes no no 8.38s
✅ REPOSITORY trufflehog yes no no 7.04s

Detailed Issues

⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114

----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https

----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.Exception: Restore operation failed.
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
   at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
   at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
   at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)

See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 7, 2026

Greptile Summary

This PR refactors GameContext from a weakly-constrained multi-context registry (backed only by a ConcurrentDictionary) into a single-active-context + type-alias model, protected by a unified lock (SyncRoot). It also addresses three open review threads: the TOCTOU race in Unbind, non-volatile reads of _currentArchitectureContext, and the missing GameContext.Unbind in the synchronous Destroy() path.

  • GameContext: introduces _currentArchitectureContext and SyncRoot lock; all read and write paths are now covered by the same lock, eliminating the previously flagged TOCTOU race and stale-read hazard.
  • Architecture.Destroy(): gains the same finally { GameContext.Unbind(GetType()); } block already added to DestroyAsync(), closing the unbind gap on the synchronous destroy path.
  • MicrosoftDiContainer: pre-freeze Get<T> / Get(Type) and ResolveCqrsRegistrationService are unified to call CollectRegisteredImplementationInstances, aligning instance-visibility semantics with GetAll.

Confidence Score: 5/5

Safe to merge. All three open review threads are correctly addressed, and the unified lock eliminates the combined-state inconsistency that existed in the prior implementation.

The unified SyncRoot lock correctly protects every read and write path on _currentArchitectureContext together with ArchitectureDictionary, closing the TOCTOU race and stale-read hazard. Both destroy paths now consistently unbind from GameContext. The MicrosoftDiContainer pre-freeze lookup unification is consistent and well-tested. The only findings are style-level nits in the test teardown.

No files require special attention. GameContext.cs is the most structurally changed file and is well-covered by new tests.

Important Files Changed

Filename Overview
GFramework.Core/Architectures/GameContext.cs Core refactor: replaces Interlocked/ConcurrentDictionary-only approach with unified SyncRoot lock. All state transitions are now atomic; the ConcurrentDictionary is retained solely to provide a lock-free live view via ArchitectureReadOnlyDictionary.
GFramework.Core/Architectures/Architecture.cs Destroy() now mirrors DestroyAsync() with a finally-guarded Unbind; both paths correctly clean up the GameContext binding even if the lifecycle layer throws.
GFramework.Core/Rule/ContextAwareBase.cs Documentation-only change; the documented stale-reference risk after architecture destruction is accurate and worth preserving for callers.
GFramework.Core/Ioc/MicrosoftDiContainer.cs Pre-freeze Get/Get(Type) and ResolveCqrsRegistrationService now share CollectRegisteredImplementationInstances, making instance visibility consistent across all pre-freeze query paths.
GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs New regression tests cover: destroy unbind, failed-init destroy unbind, post-destroy ContextAware fallback, and synchronous Destroy() unbind. SetUp/TearDown correctly use GameContext.Clear().
GFramework.Core.Tests/Architectures/GameContextTests.cs Tests updated to reflect the new single-context semantics; new cases cover different-instance rejection, alias-aware unbind retention, and context-type fallback resolution.
GFramework.Core.Tests/Rule/ContextAwareTests.cs GetContext fallback test strengthened from DoesNotThrow to asserting the actual returned instance. TearDown uses Unbind rather than Clear(); correct today but fragile if the fixture grows.
GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs New tests document pre-freeze visibility contract: RegisterPlurality aliases are visible, implementation-type registrations are not, and CQRS handler registration is verified end-to-end.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
GFramework.Core.Tests/Rule/ContextAwareTests.cs:35-39
The TearDown calls `Unbind(typeof(TestArchitectureContext))` rather than `Clear()`. This works correctly for the current fixture (SetUp adds exactly one binding), but is fragile: if any future test in this fixture adds a second alias, the cleanup is incomplete. All other test fixtures that touch `GameContext` use `Clear()` in their teardown for this exact reason.

```suggestion
    [TearDown]
    public void TearDown()
    {
        GameContext.Clear();
    }
```

### Issue 2 of 2
GFramework.Core/Architectures/GameContext.cs:21-23
**Redundant internal locking in `ConcurrentDictionary`**

All mutations to `ArchitectureDictionary` already happen exclusively inside `lock (SyncRoot)`, so `ConcurrentDictionary`'s internal per-bucket locks are never needed for writes. The only callers that benefit from `ConcurrentDictionary`'s thread-safety are external readers of `ArchitectureReadOnlyDictionary`, which see a live snapshot without holding `SyncRoot`. That use-case is valid and documented in the comment above, but worth keeping in mind if lock contention becomes a concern.

Reviews (2): Last reviewed commit: "fix(core): 修复上下文销毁解绑与并发一致性" | Re-trigger Greptile

Comment thread GFramework.Core/Architectures/GameContext.cs Outdated
Comment thread GFramework.Core/Architectures/GameContext.cs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
GFramework.Core/Architectures/Architecture.cs (1)

379-383: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Destroy()(同步已废弃方法)未调用 GameContext.Unbind(),可能遗留全局过期绑定

DestroyAsync()finally 中执行 GameContext.Unbind(GetType()),确保销毁后全局回退路径失效。但同步的 Destroy() 仅调用 _lifecycle.Destroy()不执行任何解绑

若调用方仍使用 Destroy()(尽管已标记 [Obsolete]),架构生命周期组件会被清理,但 GameContext 仍持有该架构实例的过期引用。后续任何 ContextAwareBase.GetContext() 的惰性调用都会命中这个已销毁的上下文,导致难以排查的运行时错误。

🔧 建议修复
  [Obsolete("建议使用 DestroyAsync() 以支持异步清理")]
  public virtual void Destroy()
  {
-     _lifecycle.Destroy();
+     try
+     {
+         _lifecycle.Destroy();
+     }
+     finally
+     {
+         // 与 DestroyAsync 保持一致:销毁后必须解除全局回退入口
+         GameContext.Unbind(GetType());
+     }
  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Core/Architectures/Architecture.cs` around lines 379 - 383, The
synchronous Destroy() currently only calls _lifecycle.Destroy() and omits the
GameContext.Unbind(GetType()) cleanup performed by DestroyAsync(), leaving stale
global bindings; update Destroy() (the obsolete synchronous method) to perform
the same unbind logic as DestroyAsync() — ensure GameContext.Unbind(GetType())
is invoked (ideally in a finally-equivalent block around _lifecycle.Destroy())
so ContextAwareBase.GetContext() cannot later return a destroyed instance.
🧹 Nitpick comments (5)
GFramework.Core/Architectures/GameContextProvider.cs (1)

14-21: ⚡ Quick win

GetContext() 缺少 <exception> XML 文档标注

GetContext() 调用 GameContext.GetFirstArchitectureContext(),在无活动上下文时会抛出 InvalidOperationException(对应 ContextProviderTests.cs 中的 GameContextProvider_GetContext_Should_Throw_When_Empty 测试)。按编码规范,方法可能抛出的异常必须通过 <exception> 标签声明。

📝 建议补充的 XML 文档
  /// <summary>
  /// 获取当前的架构上下文。
  /// </summary>
  /// <returns>架构上下文实例</returns>
+ /// <exception cref="InvalidOperationException">当前没有已绑定的活动架构上下文时抛出。</exception>
  public IArchitectureContext GetContext()

As per coding guidelines: "XML documentation MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Core/Architectures/GameContextProvider.cs` around lines 14 - 21,
The GetContext() XML docs must declare the possible InvalidOperationException
thrown by GameContext.GetFirstArchitectureContext(); update the method's XML
documentation to include an <exception> tag describing that
InvalidOperationException is thrown when there is no active architecture context
(as covered by
ContextProviderTests.cs::GameContextProvider_GetContext_Should_Throw_When_Empty),
while keeping the existing <summary> and <returns> intact.
GFramework.Core/Rule/ContextAwareBase.cs (1)

48-56: ⚡ Quick win

建议在 <remarks> 中补充一次性缓存的生命周期警告

GetContext() 通过回退路径拿到上下文并写入 Context 字段后,后续即使架构调用 DestroyAsync() 触发 GameContext.Unbind(),该实例的 Context 缓存也不会被清除,仍然指向已销毁的上下文。这一行为对调用方有隐含的生命周期假设,按编码规范应在 XML 文档中显式说明。

📝 建议补充的 `` 内容
  /// <remarks>
  ///     当 <see cref="Context" /> 为空时,该实现会直接回退到 <see cref="GameContext.GetFirstArchitectureContext" /> 返回的当前活动上下文。
  ///     该回退过程不执行额外同步,也不支持替换 provider;如需这些能力,请改用生成的 ContextAware 实现。
+ ///     回退结果会被缓存到 <see cref="Context" />;一旦缓存,即使关联架构随后调用 <see cref="GameContext" />.Unbind 解除绑定,
+ ///     该实例仍将持有原上下文引用,不会自动置空。
  /// </remarks>

As per coding guidelines: "If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Core/Rule/ContextAwareBase.cs` around lines 48 - 56, The XML
remarks for IContextAware.GetContext() must explicitly document that when the
method falls back to GameContext.GetFirstArchitectureContext() and assigns the
result to the Context field, that cached Context is one-time and will not be
cleared if the architecture later calls DestroyAsync() which triggers
GameContext.Unbind(); update the <remarks> to warn callers that Context may
continue to reference a destroyed context, describe the lifecycle implication
and threading/registration caveat, and point callers to prefer generated
ContextAware implementations if they need automatic cache invalidation or
replacement of the provider.
GFramework.Core/Architectures/Architecture.cs (1)

359-374: ⚡ Quick win

DestroyAsync() 的 XML 文档缺少 GameContext.Unbind 副作用说明

DestroyAsync() 现在在 finally 中执行全局解绑,这是一个重要的注册/生命周期行为变更,按编码规范必须在 XML 文档中显式说明。

📝 建议补充的 XML 文档
  /// <summary>
  ///     异步销毁架构及所有组件
  /// </summary>
+ /// <remarks>
+ ///     销毁完成后(无论 <see cref="_lifecycle" />.DestroyAsync() 是否抛出),都会调用
+ ///     <see cref="GameContext.Unbind" /> 解除当前架构类型在全局注册表中的绑定,
+ ///     确保后续惰性 <c>ContextAwareBase.GetContext()</c> 调用不会命中已销毁的上下文。
+ /// </remarks>
  public virtual async ValueTask DestroyAsync()

As per coding guidelines: "If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Core/Architectures/Architecture.cs` around lines 359 - 374, Update
the XML doc for the method DestroyAsync to explicitly call out its side effect:
it invokes _lifecycle.DestroyAsync() and then always calls
GameContext.Unbind(GetType()) in a finally block to remove the global binding
for this architecture type (preventing stale runtime contexts and affecting any
ContextAware consumers); mention that this unbind occurs even on exceptions,
that the operation is asynchronous (returns ValueTask), and note any
threading/lifecycle implications so callers know the global registration is
removed during destruction.
GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs (1)

489-497: ⚡ Quick win

测试断言可加强:仅验证不抛异常,未验证 handler 真的被注册。

Assert.DoesNotThrow 能覆盖 ResolveCqrsRegistrationService 通过实例可见性路径解析成功这一 happy path,但不能区分“注册流程实际执行”与“在解析阶段静默回退”。建议附加一个对 GetServicesUnsafe 中目标 handler 描述符的存在性断言,复用文件中已有的模式(例如 Clear_Should_Reset_Cqrs_Assembly_Deduplication_State)。

♻️ 建议补强断言
     [Test]
     public void RegisterCqrsHandlersFromAssemblies_Should_Resolve_Registration_Service_When_Registered_As_Instance()
     {
         Assert.DoesNotThrow(() =>
             _container.RegisterCqrsHandlersFromAssemblies([typeof(DeterministicOrderNotification).Assembly]));
+
+        Assert.That(
+            _container.GetServicesUnsafe.Any(static descriptor =>
+                descriptor.ServiceType == typeof(INotificationHandler<DeterministicOrderNotification>)),
+            Is.True);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs` around lines 489 -
497, The test
RegisterCqrsHandlersFromAssemblies_Should_Resolve_Registration_Service_When_Registered_As_Instance
only asserts no exception; update it to also verify the handler descriptor was
actually registered by calling GetServicesUnsafe for the CQRS registration
service and asserting that a descriptor for DeterministicOrderNotification (or
the expected handler type from the assembly) exists; reuse the pattern used in
Clear_Should_Reset_Cqrs_Assembly_Deduplication_State to locate the registration
via ResolveCqrsRegistrationService and assert the presence (and optionally
count) of the handler descriptor rather than relying solely on
Assert.DoesNotThrow.
GFramework.Core/Architectures/GameContext.cs (1)

90-114: ⚡ Quick win

XML 文档未跟随语义变更同步更新。

下列成员的语义在本次重构中已发生变化或与 _currentArchitectureContext 的生命周期/线程行为强相关,但 XML 文档没有相应更新:

  • Get<T> / TryGet<T>:现已优先返回 _currentArchitectureContext(如果可分配到 T),再退回字典查找。文档仍是泛化的“获取指定类型的架构上下文实例”,未体现新的命中顺序。
  • Unbind:增加了非空校验,并会在“最后一个别名被移除”时清空 _currentArchitectureContext;但既缺 <exception cref="ArgumentNullException"> 标注,也未说明对当前活动上下文的副作用。
  • Clear:除清空字典外还会清空 _currentArchitectureContext,文档未提及。
📝 建议补全的 XML 文档要点
     /// <summary>
-    ///     获取指定类型的架构上下文实例
+    ///     获取指定类型的架构上下文实例。
+    ///     优先返回当前活动上下文(若可分配到 <typeparamref name="T" />),否则按显式绑定的类型别名在字典中查找。
     /// </summary>
     ...
     public static T Get<T>() where T : class, IArchitectureContext
     ...
     /// <summary>
-    ///     尝试获取指定类型的架构上下文实例
+    ///     尝试获取指定类型的架构上下文实例。
+    ///     优先匹配当前活动上下文(若可分配到 <typeparamref name="T" />),否则按显式绑定的类型别名在字典中查找。
     /// </summary>
     ...
     public static bool TryGet<T>(out T? context)
     ...
     /// <summary>
-    ///     移除指定类型的架构上下文绑定
+    ///     移除指定类型的架构上下文绑定。
+    ///     若被移除的别名是当前活动上下文的最后一个引用,则同步清空 <c>_currentArchitectureContext</c>;
+    ///     否则保留当前活动上下文不变。
     /// </summary>
     /// <param name="architectureType">要移除的架构类型</param>
+    /// <exception cref="ArgumentNullException"><paramref name="architectureType" /> 为 <see langword="null" />。</exception>
     public static void Unbind(Type architectureType)
     ...
     /// <summary>
-    ///     清空所有架构上下文绑定
+    ///     清空所有架构上下文绑定,并同时重置当前活动上下文。
+    ///     调用后 <see cref="GetFirstArchitectureContext" /> 将抛出异常,直到再次 <see cref="Bind" />。
     /// </summary>
     public static void Clear()

As per coding guidelines: "Any change to public API, lifecycle semantics, module behavior, or extension points MUST update related XML docs in C#" 与 "If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly"。

Also applies to: 133-159

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@GFramework.Core/Architectures/GameContext.cs` around lines 90 - 114, The XML
docs for Get<T>, TryGet<T>, Unbind, and Clear are out-of-date: update their
summaries and relevant tags to reflect the new lifecycle and lookup semantics
(Get<T>/TryGet<T> now prefer _currentArchitectureContext if assignable to T
before falling back to ArchitectureDictionary), document thread/lifecycle
side-effects (Unbind now checks for null, removes aliases and clears
_currentArchitectureContext when the last alias is removed — add <exception
cref="ArgumentNullException"> where appropriate and explain the side effect on
the active context), and note that Clear empties both ArchitectureDictionary and
_currentArchitectureContext; ensure any threading/ownership/disposal
implications are described for these members.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@GFramework.Core/Architectures/GameContext.cs`:
- Around line 137-149: The Unbind/Bind/Clear sequence can suffer a TOCTOU race
between ArchitectureDictionary and _currentArchitectureContext; wrap all
compound operations that modify both the dictionary and the current context
(methods Unbind, Bind, and Clear and any helper that updates
_currentArchitectureContext alongside ArchitectureDictionary) inside a single
private lock (e.g., a dedicated object like _contextLock) so dictionary
removals/additions and the Interlocked/assignment of _currentArchitectureContext
are performed atomically; update GetFirstArchitectureContext (and document
Get<T>/TryGet<T> behavior) to read under the same lock or use a volatile read to
avoid observing a null _currentArchitectureContext when the dictionary still
contains the context.

---

Outside diff comments:
In `@GFramework.Core/Architectures/Architecture.cs`:
- Around line 379-383: The synchronous Destroy() currently only calls
_lifecycle.Destroy() and omits the GameContext.Unbind(GetType()) cleanup
performed by DestroyAsync(), leaving stale global bindings; update Destroy()
(the obsolete synchronous method) to perform the same unbind logic as
DestroyAsync() — ensure GameContext.Unbind(GetType()) is invoked (ideally in a
finally-equivalent block around _lifecycle.Destroy()) so
ContextAwareBase.GetContext() cannot later return a destroyed instance.

---

Nitpick comments:
In `@GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs`:
- Around line 489-497: The test
RegisterCqrsHandlersFromAssemblies_Should_Resolve_Registration_Service_When_Registered_As_Instance
only asserts no exception; update it to also verify the handler descriptor was
actually registered by calling GetServicesUnsafe for the CQRS registration
service and asserting that a descriptor for DeterministicOrderNotification (or
the expected handler type from the assembly) exists; reuse the pattern used in
Clear_Should_Reset_Cqrs_Assembly_Deduplication_State to locate the registration
via ResolveCqrsRegistrationService and assert the presence (and optionally
count) of the handler descriptor rather than relying solely on
Assert.DoesNotThrow.

In `@GFramework.Core/Architectures/Architecture.cs`:
- Around line 359-374: Update the XML doc for the method DestroyAsync to
explicitly call out its side effect: it invokes _lifecycle.DestroyAsync() and
then always calls GameContext.Unbind(GetType()) in a finally block to remove the
global binding for this architecture type (preventing stale runtime contexts and
affecting any ContextAware consumers); mention that this unbind occurs even on
exceptions, that the operation is asynchronous (returns ValueTask), and note any
threading/lifecycle implications so callers know the global registration is
removed during destruction.

In `@GFramework.Core/Architectures/GameContext.cs`:
- Around line 90-114: The XML docs for Get<T>, TryGet<T>, Unbind, and Clear are
out-of-date: update their summaries and relevant tags to reflect the new
lifecycle and lookup semantics (Get<T>/TryGet<T> now prefer
_currentArchitectureContext if assignable to T before falling back to
ArchitectureDictionary), document thread/lifecycle side-effects (Unbind now
checks for null, removes aliases and clears _currentArchitectureContext when the
last alias is removed — add <exception cref="ArgumentNullException"> where
appropriate and explain the side effect on the active context), and note that
Clear empties both ArchitectureDictionary and _currentArchitectureContext;
ensure any threading/ownership/disposal implications are described for these
members.

In `@GFramework.Core/Architectures/GameContextProvider.cs`:
- Around line 14-21: The GetContext() XML docs must declare the possible
InvalidOperationException thrown by GameContext.GetFirstArchitectureContext();
update the method's XML documentation to include an <exception> tag describing
that InvalidOperationException is thrown when there is no active architecture
context (as covered by
ContextProviderTests.cs::GameContextProvider_GetContext_Should_Throw_When_Empty),
while keeping the existing <summary> and <returns> intact.

In `@GFramework.Core/Rule/ContextAwareBase.cs`:
- Around line 48-56: The XML remarks for IContextAware.GetContext() must
explicitly document that when the method falls back to
GameContext.GetFirstArchitectureContext() and assigns the result to the Context
field, that cached Context is one-time and will not be cleared if the
architecture later calls DestroyAsync() which triggers GameContext.Unbind();
update the <remarks> to warn callers that Context may continue to reference a
destroyed context, describe the lifecycle implication and threading/registration
caveat, and point callers to prefer generated ContextAware implementations if
they need automatic cache invalidation or replacement of the provider.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 672e4714-2ac7-4fc6-8daa-1afce38c6c9c

📥 Commits

Reviewing files that changed from the base of the PR and between c2d2228 and ff04a4f.

📒 Files selected for processing (18)
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContext.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core/Rule/ContextAwareBase.cs
  • ai-plan/public/README.md
  • ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md
  • ai-plan/public/single-context-priority/traces/single-context-priority-trace.md
  • docs/zh-CN/core/context.md
  • docs/zh-CN/core/rule.md
  • docs/zh-CN/source-generators/context-aware-generator.md
  • docs/zh-CN/source-generators/context-get-generator.md
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build and Test
  • GitHub Check: Code Quality & Security
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) in C#
XML documentation MUST use <summary>, <param>, <returns>, <exception>, and <remarks> where applicable, and explain intent, contract, and usage constraints instead of restating syntax
If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why abstraction exists, and when to use instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Do not rely on implicit imports. Declare every required using explicitly in C#
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C#
Use namespace pattern GFramework.{Module}.{Feature} with PascalCase segments in C#
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, Interfaces use I prefix, Parameters and locals use camelCase, Private fields use _camelCase
Use Allman braces style for C#
Keep using directives at the top of the file and sort them consistently in C#
Prefer one primary type per file unless surrounding project already uses different local pattern
Prefer explicit, readable code over clever shorthand in framework internals
M...

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*[!.]*

📄 CodeRabbit inference engine (AGENTS.md)

For files with shebang lines, keep shebang as first line and place license header immediately after it

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • ai-plan/public/README.md
  • docs/zh-CN/core/rule.md
  • ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md
  • docs/zh-CN/source-generators/context-aware-generator.md
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • docs/zh-CN/core/context.md
  • docs/zh-CN/source-generators/context-get-generator.md
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • ai-plan/public/single-context-priority/traces/single-context-priority-trace.md
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py,sh}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py,sh}: All generated or modified code MUST include clear and meaningful comments where required by documentation rules
Comments MUST NOT be trivial, redundant, or misleading. Prefer explaining why and when, not just what. Code should remain understandable without requiring external context
Avoid obvious comments such as // increment i

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{csproj,cs}

📄 CodeRabbit inference engine (AGENTS.md)

Framework runtime, abstractions, and meta-package projects MUST NOT reference *.SourceGenerators* projects or packages, and MUST NOT use source-generator attributes

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation. Do not use tabs

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}

📄 CodeRabbit inference engine (AGENTS.md)

Keep line length readable. Around 120 characters is preferred upper bound

Files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form

Files:

  • ai-plan/public/README.md
  • docs/zh-CN/core/rule.md
  • ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md
  • docs/zh-CN/source-generators/context-aware-generator.md
  • docs/zh-CN/core/context.md
  • docs/zh-CN/source-generators/context-get-generator.md
  • ai-plan/public/single-context-priority/traces/single-context-priority-trace.md
docs/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Documentation should be organized with Chinese content in docs/zh-CN/ and structured to include getting started, module-specific capabilities (Core, Game, Godot, ECS), source generator usage, tutorials, best practices, and troubleshooting

Files:

  • docs/zh-CN/core/rule.md
  • docs/zh-CN/source-generators/context-aware-generator.md
  • docs/zh-CN/core/context.md
  • docs/zh-CN/source-generators/context-get-generator.md
**/*Abstractions/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

Abstractions projects should only contain interfaces and contract definitions without any runtime implementation logic

Files:

  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Core/Rule/ContextAwareBase.cs
  • GFramework.Core.Tests/Rule/ContextAwareTests.cs
  • GFramework.Core/Architectures/Architecture.cs
  • GFramework.Core/Architectures/GameContextProvider.cs
  • GFramework.Core.Tests/Architectures/ContextProviderTests.cs
  • GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs
  • GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
  • GFramework.Core/Ioc/MicrosoftDiContainer.cs
  • GFramework.Core.Tests/Architectures/GameContextTests.cs
  • GFramework.Core.Abstractions/Ioc/IIocContainer.cs
  • GFramework.Core/Architectures/GameContext.cs
🔇 Additional comments (17)
docs/zh-CN/core/rule.md (1)

93-93: LGTM!

新增的"自动回退机制"说明与 ContextAwareBase.cs 实现完全对齐。

docs/zh-CN/source-generators/context-aware-generator.md (1)

93-105: LGTM!

两条路径的回退策略区分说明清晰,与代码实现保持一致。

docs/zh-CN/core/context.md (1)

143-151: LGTM!

回退机制的定位和新代码推荐路径表述清晰,与 PR 整体语义对齐。

GFramework.Core.Tests/Architectures/ContextProviderTests.cs (1)

40-79: LGTM!

将绑定键从 typeof(TestArchitectureContext) 改为 typeof(TestArchitecture) 正确对齐了 Architecture.DestroyAsync() 调用 GameContext.Unbind(GetType()) 的语义,并且 TryGetContext<TestArchitectureContext> 的跨类型兼容性查询也得到了验证。

GFramework.Core.Tests/Rule/ContextAwareTests.cs (1)

23-39: 绑定键类型不影响当前活动上下文的设置,测试逻辑正确

GameContext.Bind()architectureType 参数仅作为 ArchitectureDictionary 的字典键,不控制 _currentArchitectureContext 的赋值。无论使用 typeof(TestArchitectureContext) 还是 typeof(TestArchitecture) 作为绑定键,都会在首次调用 Bind 时通过 Interlocked.CompareExchange 将同一 context 实例设置为当前活动上下文。

GetContext_Should_Return_CurrentArchitectureContext_When_Not_Set 测试在 SetUp 中绑定上下文后,调用 GetContext() 时正确回退到当前活动上下文并返回 _mockContext。本文件使用 typeof(TestArchitectureContext) 作为键在 SetUpTearDown 中一致,测试逻辑完全正确。

注:ContextProviderTests.cs 使用 typeof(TestArchitecture) 作为绑定键,与本文件不同。为了与生产代码中 Architecture.DestroyAsync() 调用 GameContext.Unbind(GetType()) 的实际行为对齐,建议统一使用 typeof(TestArchitecture) 作为绑定键。

			> Likely an incorrect or invalid review comment.
ai-plan/public/README.md (1)

45-72: LGTM!

新增的 single-context-priority 活动主题与 worktree 映射结构与文件其他条目保持一致。

GFramework.Core.Abstractions/Ioc/IIocContainer.cs (1)

144-238: LGTM!

新增的 <remarks> 准确描述了 MicrosoftDiContainer 在预冻结阶段的实例可见性语义,与实现端 CollectRegisteredImplementationInstances 的行为一致;<see cref="Freeze" /> 在同一接口内可正常解析。

ai-plan/public/single-context-priority/todos/single-context-priority-tracking.md (1)

1-59: LGTM!

跟踪文档结构完整,恢复点、风险、验证记录都清晰呈现。

docs/zh-CN/source-generators/context-get-generator.md (1)

654-705: LGTM!

“自定义上下文来源”小节与已有测试/手动装配示例(SetContextProvider / ResetContextProvider)保持一致,分析器排除场景描述也匹配单活动上下文模型。

GFramework.Core.Tests/Architectures/ArchitectureLifecycleBehaviorTests.cs (1)

186-238: LGTM!

三个回归测试完整覆盖了 DestroyAsync() 解绑全局 GameContext 的核心契约:成功初始化路径、FailedInitialization 路径、以及销毁后新 ContextAwareBase 实例不再回退到过期上下文。LifecycleContextAwareProbe 作为最小探针是合适的设计。

ai-plan/public/single-context-priority/traces/single-context-priority-trace.md (1)

1-44: LGTM!

时间线追踪覆盖了 RP-001/RP-002 两阶段的实现摘要、验证结果以及 MSBuild copy 冲突的规避说明,便于后续回看。

GFramework.Core/Ioc/MicrosoftDiContainer.cs (3)

600-615: LGTM!

ResolveCqrsRegistrationService 复用统一的实例可见性管线后,错误信息也明确指向“注册阶段必须以实例绑定预物化”的契约。LastOrDefault 与 MS DI 冻结后 GetService<T>() 的“最后注册胜出”语义对齐,覆盖 RegisterInfrastructure 多次接入同一 seam 的场景。


631-674: LGTM!

Get<T>() / Get(Type) 的预冻结路径统一走 CollectRegisteredImplementationInstances,与 GetAll 的可见性规则一致;Get(Type) 入口处补充了 ArgumentNullException.ThrowIfNull(type),防御性合理。


801-889: LGTM!

新增的实例收集与去重三件套(CollectRegisteredImplementationInstancesBuildPreferredVisibleServiceTypesSelectPreferredVisibleServiceType)逻辑清晰:

  • 通过 ReferenceEqualityComparer 按实例分组,避免值相等性误判;
  • 优先保留调用方请求类型,再按“同 ServiceType 注册次数最多”稳定打破并列,正好匹配 GetAll_Should_Preserve_Duplicate_Registrations_For_The_Same_ServiceType_While_Deduplicating_Aliases 的预期;
  • 826-833 行对 ImplementationFactory / ImplementationType 的空分支加注释而非删除,能直观表达“预冻结故意不激活”这一契约,与 IIocContainer<remarks> 文档前后呼应。

XML 文档与 Allman 风格符合仓库规范。

GFramework.Core.Tests/Architectures/GameContextTests.cs (2)

76-238: 测试覆盖与新语义对齐良好。

新增/调整的用例覆盖了 “拒绝绑定不同实例”、“按上下文具体类型回查”、“仅按架构类型绑定时 Get<T> 仍能命中”、“移除最后一个别名后清空当前上下文”、以及 “保留其他别名时不清空当前上下文” 这几条核心路径,并配合 ClearGetFirstArchitectureContext 抛异常的断言形成闭环。


79-89: AnotherTestArchitectureContext 类型已在测试项目中正确定义,无需修改。

该类型已在 GFramework.Core.Tests/Architectures/AnotherTestArchitectureContext.cs 中声明为公开类,继承自 TestArchitectureContext,并包含完整的 XML 文档注释。测试代码可以正常编译和运行。

GFramework.Core/Architectures/GameContext.cs (1)

39-46: 单实例追踪与回退查找的整体设计清晰。

Bind 的非空校验、GetFirstArchitectureContext 的语义收敛、GetByType 中 “显式别名优先 → 当前活动上下文按类型兼容回退” 的两段式查找、以及 Get<T>/TryGet<T> 的快路径,逻辑层次分明,错误信息也具备可观察性。除上文指出的并发原子性与文档同步问题外,主体改动方向合理。

Also applies to: 59-87, 96-131

Comment thread GFramework.Core/Architectures/GameContext.cs
- 修复 GameContext 的别名字典与当前活动上下文同步边界,避免解绑与读取路径出现状态漂移
- 修复 Architecture.Destroy() 缺少全局解绑的问题,并补充相关生命周期 XML 文档
- 更新回归测试、CQRS 注册断言与 single-context-priority 跟踪记录
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

Summary

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Other ❓ Flaky 🍂 Duration ⏱️
2300    ↑1 2300    ↑1 0 0 0 0 38.1s    ↓90ms

Test Results

passed 2300 passed ↑1

Details

tests 2300 tests ↑1
clock 38.1s ↓90ms
tool nunit
build CI - Build & Test arrow-right build-and-test link #1073
pull-request Refactor/single context priority link #332

Insights

Average Tests per Run Total Flaky Tests Total Failed Slowest Test (p95)
2300 0 0 4.2s

build-and-test: Run #1073

Tests 📝 Passed ✅ Failed ❌ Skipped ⏭️ Pending ⏳ Other ❓ Flaky 🍂 Duration ⏱️
2300 2300 0 0 0 0 0 38.1s

🎉 All tests passed!

Slowest Tests

Test 📝 Results 📊 Duration (avg) ⏱️ Duration (p95) ⏱️
CreateStream_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently 2 4.1s 4.2s
Does_Not_Report_When_FieldInjectedModel_Is_Registered 2 2.2s 2.3s
Generates_Scene_Behavior_Boilerplate 2 1.9s 1.9s
CleanupDuringAcquire_Should_NotCauseRaceCondition 2 1.1s 1.1s
Append_ShouldNotBlock 2 1.0s 1.0s
Context_Caching_Should_Improve_Performance 2 776ms 777ms
PendingCount_ShouldReflectQueuedEntries 2 501ms 501ms
Cleanup_Should_NotRemoveActiveLocks 2 404ms 405ms
Cleanup_Should_RemoveUnusedLocks 2 401ms 401ms
Generates_Precise_Assembly_Type_Lookups_For_Inaccessible_External_Generic_Definitions_With_Visible_Type_Arguments 2 322ms 324ms

± Comparison with run #1072 at e3209a1 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 2 runs.

Github Test Reporter by CTRF 💚

@GeWuYou GeWuYou merged commit c3df2b2 into main May 7, 2026
7 checks passed
@GeWuYou GeWuYou deleted the refactor/single-context-priority branch May 7, 2026 03:34
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