Refactor/cqrs architecture decoupling todo 5#224
Conversation
- 实现ArchitectureContext提供系统、模型、工具等组件访问管理 - 添加CqrsDispatcher作为GFramework自有CQRS运行时分发器 - 集成Microsoft.Extensions.DependencyInjection作为IoC容器适配器 - 实现完整的命令、查询、事件处理机制 - 支持上下文感知处理器注入架构上下文 - 提供管道行为链处理机制 - 实现流式请求处理功能 - 添加服务实例缓存和优先级排序支持
- 实现 MicrosoftDiContainer 类,提供 Microsoft.Extensions.DependencyInjection 的适配器 - 添加 DefaultCqrsHandlerRegistrar 默认 CQRS 处理器注册器实现 - 配置 GitHub Actions CI/CD 工作流,包含代码质量检查和构建测试任务 - 设置 .NET 8/9/10 多版本支持和缓存策略 - 添加单元测试覆盖 IoC 容器的各项功能,包括注册、解析和生命周期管理 - 实现线程安全的读写锁机制保护容器操作 - 支持 CQRS 处理器和管道行为的注册管理
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough将 CQRS 抽象提取到新项目 Changes
Sequence Diagram(s)sequenceDiagram
participant Caller as ArchitectureContext
participant Container as IIocContainer
participant Runtime as ICqrsRuntime (CqrsDispatcher)
participant Handler as CQRS Handler(s)
Caller->>Container: Lazy resolve ICqrsRuntime
Container-->>Caller: ICqrsRuntime instance
Caller->>Runtime: SendAsync(context, IRequest)
Runtime->>Runtime: Prepare handler pipeline (with context)
Runtime->>Handler: Invoke handler.Handle(request, cancellation)
Handler-->>Runtime: response
Runtime-->>Caller: return response
sequenceDiagram
participant TestSetup as TestRuntime.RegisterInfrastructure
participant Container as IIocContainer
participant Runtime as ICqrsRuntime
participant Registrar as ICqrsHandlerRegistrar
TestSetup->>Container: Check registrations
alt missing
TestSetup->>Runtime: construct CqrsDispatcher(container, logger)
TestSetup->>Registrar: construct DefaultCqrsHandlerRegistrar(container, logger)
TestSetup->>Container: register Runtime & Registrar instances
end
TestSetup-->>Container: ready for RegisterHandlers calls
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 分钟 Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
- 在ContainerRegistrationFixtures.cs中添加GFramework.Core.Abstractions.Cqrs命名空间引用 - 在MicrosoftDiContainerTests.cs中添加GFramework.Core.Abstractions.Cqrs命名空间引用 - 统一测试文件中的依赖注入配置 - 确保CQRS相关接口的正确引用路径
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (5)
GFramework.Cqrs.Abstractions/Directory.Build.props (1)
9-16: 分析器包版本与其他项目不一致。
Meziantou.Analyzer版本2.0.264和Meziantou.Polyfill版本1.0.71与GFramework.Core.Abstractions中使用的版本(分别为3.0.46和1.0.109)不一致。建议统一版本以确保所有项目应用相同的代码分析规则。♻️ 建议统一版本
<ItemGroup> - <PackageReference Include="Meziantou.Analyzer" Version="2.0.264"> + <PackageReference Include="Meziantou.Analyzer" Version="3.0.46"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> - <PackageReference Include="Meziantou.Polyfill" Version="1.0.71"> + <PackageReference Include="Meziantou.Polyfill" Version="1.0.109"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> </ItemGroup>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Cqrs.Abstractions/Directory.Build.props` around lines 9 - 16, Update the analyzer package versions to match the ones used in GFramework.Core.Abstractions: change the PackageReference for Meziantou.Analyzer from Version="2.0.264" to Version="3.0.46" and the PackageReference for Meziantou.Polyfill from Version="1.0.71" to Version="1.0.109" so all projects use the same analyzer/polyfill versions (look for the PackageReference entries with Include="Meziantou.Analyzer" and Include="Meziantou.Polyfill" and update their Version attributes accordingly).GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj (1)
10-10:WarningLevel设为 0 会禁用所有编译器警告。
<WarningLevel>0</WarningLevel>会完全抑制编译器警告,可能隐藏潜在问题。建议使用更精细的控制(如NoWarn指定具体警告编号),或者移除此设置以保留默认警告级别。♻️ 建议移除或调整
<IsPackable>false</IsPackable> <IsTestProject>true</IsTestProject> - <WarningLevel>0</WarningLevel> </PropertyGroup>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj` at line 10, 当前项目文件中将 MSBuild 属性 WarningLevel 设置为 0(WarningLevel)会完全禁用编译器警告;请在 GFramework.Cqrs.Tests.csproj 中删除该 WarningLevel 元素或将其恢复为默认(例如 4),或者替代性地移除该设置并使用 NoWarn 列表来屏蔽特定警告编号(例如 在 PropertyGroup 中添加 NoWarn 而不是使用 WarningLevel=0),以便保留有用的编译器警告并只抑制确切需要忽略的警告。GFramework.Core/Architectures/ArchitectureContext.cs (1)
23-23: 延迟初始化模式在并发场景下可能重复解析
??=操作符不是原子的,在高并发场景下多个线程可能同时读取_cqrsRuntime为 null 并调用_container.Get<ICqrsRuntime>()。由于容器应返回同一个单例实例,这不会导致正确性问题,仅是轻微的效率损失。如果
ArchitectureContext预期会被高频并发访问,可考虑使用Lazy<T>或双重检查锁定模式。♻️ 可选:使用 Lazy<T> 确保线程安全的单次初始化
- private ICqrsRuntime? _cqrsRuntime; + private readonly Lazy<ICqrsRuntime> _cqrsRuntime; + public ArchitectureContext(IIocContainer container) + { + _container = container ?? throw new ArgumentNullException(nameof(container)); + _cqrsRuntime = new Lazy<ICqrsRuntime>(() => + _container.Get<ICqrsRuntime>() ?? throw new InvalidOperationException("ICqrsRuntime not registered")); + } - private ICqrsRuntime CqrsRuntime => _cqrsRuntime ??= - _container.Get<ICqrsRuntime>() ?? throw new InvalidOperationException("ICqrsRuntime not registered"); + private ICqrsRuntime CqrsRuntime => _cqrsRuntime.Value;Also applies to: 30-31
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core/Architectures/ArchitectureContext.cs` at line 23, The lazy initialization of _cqrsRuntime in ArchitectureContext using the ??= pattern is not thread-safe under high concurrency; update the initialization to a thread-safe one-time resolver (e.g., replace the ??= logic with a Lazy<ICqrsRuntime> or implement double-checked locking inside the ArchitectureContext) so _container.Get<ICqrsRuntime>() is invoked only once; apply the same change to the other similar runtime fields referenced around the same area to ensure all deferred resolves (fields like _cqrsRuntime and the other runtime fields at lines 30-31) are initialized atomically and consistently.GFramework.Cqrs.Tests/CqrsTestRuntime.cs (1)
17-116: 测试项目间存在完整的代码重复此文件与
GFramework.Core.Tests/CqrsTestRuntime.cs内容几乎完全相同。建议考虑以下方案之一:
- 将
CqrsTestRuntime提取到共享测试基础设施项目中- 通过
InternalsVisibleTo让一个测试项目直接引用另一个项目的类- 如果确实需要独立副本,添加注释说明原因
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Cqrs.Tests/CqrsTestRuntime.cs` around lines 17 - 116, Duplicate test helper: the CqrsTestRuntime class (including RegisterInfrastructure, RegisterHandlers and reflection symbols like CqrsHandlerRegistrarType, RegisterHandlersMethod, CqrsDispatcherConstructor, DefaultCqrsHandlerRegistrarConstructor) is duplicated across test projects; fix by either extracting CqrsTestRuntime into a shared test-infra project and referencing it from both tests, or expose the original via InternalsVisibleTo so the other test project reuses the existing CqrsTestRuntime, or if duplication is intentional keep a short comment atop the class explaining why this copy exists and referencing the canonical source.GFramework.Core.Tests/CqrsTestRuntime.cs (1)
42-47:throwOnError: true已保证抛出异常,后续?? throw为不可达代码当
GetType的throwOnError参数为true时,若类型不存在会直接抛出TypeLoadException,因此?? throw new InvalidOperationException(...)永远不会执行。可简化为仅使用!操作符。♻️ 建议简化
private static readonly Type CqrsDispatcherType = typeof(ArchitectureContext).Assembly .GetType( "GFramework.Core.Cqrs.Internal.CqrsDispatcher", - throwOnError: true)! - ?? throw new InvalidOperationException( - "Failed to locate CqrsDispatcher type."); + throwOnError: true)!; private static readonly Type DefaultCqrsHandlerRegistrarType = typeof(ArchitectureContext).Assembly .GetType( "GFramework.Core.Cqrs.Internal.DefaultCqrsHandlerRegistrar", - throwOnError: true)! - ?? throw new InvalidOperationException( - "Failed to locate DefaultCqrsHandlerRegistrar type."); + throwOnError: true)!;Also applies to: 62-67
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core.Tests/CqrsTestRuntime.cs` around lines 42 - 47, The code uses Assembly.GetType(..., throwOnError: true) followed by a redundant null-coalescing check (e.g., the CqrsDispatcherType static initializer); because throwOnError:true already throws when the type isn't found the subsequent "?? throw new InvalidOperationException(...)" is unreachable—simplify the initializer by removing the "?? throw ..." and rely on the non-null assertion (!) after GetType (or alternatively set throwOnError:false and keep the null check if you prefer explicit InvalidOperationException); apply the same simplification to the other similar static Type initializer found at the second occurrence (lines 62-67).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.cs`:
- Around line 19-24: The compilation error is caused by missing using for the
CQRS interfaces: add the appropriate using that exposes INotification and
INotificationHandler<> (for example, add "using
GFramework.Core.Abstractions.Cqrs;" or the actual namespace where those
interfaces live) at the top of ContainerRegistrationFixtures.cs so
DeterministicOrderNotification and DeterministicOrderNotificationHandler can
resolve INotification and INotificationHandler<DeterministicOrderNotification>.
In `@GFramework.Cqrs.Tests/CqrsTestRuntime.cs`:
- Around line 1-8: The file is missing the System.Reflection import required for
types like MethodInfo, BindingFlags, ConstructorInfo, and Assembly; add "using
System.Reflection;" to the top of the file alongside the other using directives
so references to MethodInfo, BindingFlags, ConstructorInfo and Assembly resolve
and the project compiles.
In `@GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj`:
- Around line 14-17: Update the Microsoft.NET.Test.Sdk package reference to a
valid published version by changing the Version attribute value for the
PackageReference with Include="Microsoft.NET.Test.Sdk" from "18.4.0" to
"18.3.0"; leave the other PackageReference entries (Moq, NUnit,
NUnit3TestAdapter) unchanged. Ensure the csproj builds and restore succeeds
after the change.
In `@GFramework.Cqrs.Tests/Logging/TestLogger.cs`:
- Line 17: 文件位于 GFramework.Cqrs.Tests/Logging/TestLogger.cs,但命名空间声明为
GFramework.Core.Tests.Logging,导致命名空间与项目结构不匹配;请在 TestLogger 类所在文件中将命名空间改为
GFramework.Cqrs.Tests.Logging(或将文件移动到与 GFramework.Core.Tests.Logging 匹配的项目),确保
namespace 声明与项目/文件夹结构一致并且引用 TestLogger 的单元测试可以正常解析。
---
Nitpick comments:
In `@GFramework.Core.Tests/CqrsTestRuntime.cs`:
- Around line 42-47: The code uses Assembly.GetType(..., throwOnError: true)
followed by a redundant null-coalescing check (e.g., the CqrsDispatcherType
static initializer); because throwOnError:true already throws when the type
isn't found the subsequent "?? throw new InvalidOperationException(...)" is
unreachable—simplify the initializer by removing the "?? throw ..." and rely on
the non-null assertion (!) after GetType (or alternatively set
throwOnError:false and keep the null check if you prefer explicit
InvalidOperationException); apply the same simplification to the other similar
static Type initializer found at the second occurrence (lines 62-67).
In `@GFramework.Core/Architectures/ArchitectureContext.cs`:
- Line 23: The lazy initialization of _cqrsRuntime in ArchitectureContext using
the ??= pattern is not thread-safe under high concurrency; update the
initialization to a thread-safe one-time resolver (e.g., replace the ??= logic
with a Lazy<ICqrsRuntime> or implement double-checked locking inside the
ArchitectureContext) so _container.Get<ICqrsRuntime>() is invoked only once;
apply the same change to the other similar runtime fields referenced around the
same area to ensure all deferred resolves (fields like _cqrsRuntime and the
other runtime fields at lines 30-31) are initialized atomically and
consistently.
In `@GFramework.Cqrs.Abstractions/Directory.Build.props`:
- Around line 9-16: Update the analyzer package versions to match the ones used
in GFramework.Core.Abstractions: change the PackageReference for
Meziantou.Analyzer from Version="2.0.264" to Version="3.0.46" and the
PackageReference for Meziantou.Polyfill from Version="1.0.71" to
Version="1.0.109" so all projects use the same analyzer/polyfill versions (look
for the PackageReference entries with Include="Meziantou.Analyzer" and
Include="Meziantou.Polyfill" and update their Version attributes accordingly).
In `@GFramework.Cqrs.Tests/CqrsTestRuntime.cs`:
- Around line 17-116: Duplicate test helper: the CqrsTestRuntime class
(including RegisterInfrastructure, RegisterHandlers and reflection symbols like
CqrsHandlerRegistrarType, RegisterHandlersMethod, CqrsDispatcherConstructor,
DefaultCqrsHandlerRegistrarConstructor) is duplicated across test projects; fix
by either extracting CqrsTestRuntime into a shared test-infra project and
referencing it from both tests, or expose the original via InternalsVisibleTo so
the other test project reuses the existing CqrsTestRuntime, or if duplication is
intentional keep a short comment atop the class explaining why this copy exists
and referencing the canonical source.
In `@GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj`:
- Line 10: 当前项目文件中将 MSBuild 属性 WarningLevel 设置为 0(WarningLevel)会完全禁用编译器警告;请在
GFramework.Cqrs.Tests.csproj 中删除该 WarningLevel 元素或将其恢复为默认(例如 4),或者替代性地移除该设置并使用
NoWarn 列表来屏蔽特定警告编号(例如 在 PropertyGroup 中添加 NoWarn 而不是使用
WarningLevel=0),以便保留有用的编译器警告并只抑制确切需要忽略的警告。
🪄 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: 7b9f425b-3d3b-4536-b949-3d97adb184d7
📒 Files selected for processing (45)
.github/workflows/ci.ymlGFramework.Core.Abstractions/Cqrs/ICqrsRuntime.csGFramework.Core.Abstractions/GFramework.Core.Abstractions.csprojGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core/Architectures/ArchitectureContext.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.csGFramework.Core/GFramework.Core.csprojGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Core/Services/Modules/CqrsRuntimeModule.csGFramework.Core/Services/ServiceModuleManager.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommand.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.csGFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.csGFramework.Cqrs.Abstractions/Cqrs/IInput.csGFramework.Cqrs.Abstractions/Cqrs/INotification.csGFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.csGFramework.Cqrs.Abstractions/Cqrs/IPipelineBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IRequest.csGFramework.Cqrs.Abstractions/Cqrs/IRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequest.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/MessageHandlerDelegate.csGFramework.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQuery.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Cqrs.Abstractions/Cqrs/Unit.csGFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csprojGFramework.Cqrs.Abstractions/GlobalUsings.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/Logging/TestLogger.csGFramework.Cqrs.Tests/Mediator/MediatorAdvancedFeaturesTests.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Cqrs.Tests/Mediator/MediatorComprehensiveTests.csGFramework.Cqrs/GFramework.Cqrs.csprojGFramework.csprojGFramework.sln
💤 Files with no reviewable changes (4)
- GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs
- GFramework.Cqrs.Tests/Mediator/MediatorComprehensiveTests.cs
- GFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.cs
- GFramework.Cqrs.Tests/Mediator/MediatorAdvancedFeaturesTests.cs
📜 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). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, and edge cases
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions, and design rationale
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions, and diagnostic or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every requiredusingexplicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, constants use PascalCase; interfaces useIprefix; parameters and locals use camelCase; private fields use_camelCase
Use 4 spaces for indentation (not tabs), use Allman braces, and keepusingdirectives at the top of the file sorted consistently
Prefer one primary type per file unless the surrounding project alread...
Files:
GFramework.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.csGFramework.Cqrs.Abstractions/Cqrs/IInput.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.csGFramework.Core/Services/ServiceModuleManager.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.csGFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.csGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/Logging/TestLogger.csGFramework.Core.Abstractions/Cqrs/ICqrsRuntime.csGFramework.Cqrs.Abstractions/GlobalUsings.csGFramework.Core/Services/Modules/CqrsRuntimeModule.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Architectures/ArchitectureContext.cs
**/*.{cs,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Files:
GFramework.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.csGFramework.Cqrs.Abstractions/Cqrs/IInput.csGFramework.Core.Abstractions/GFramework.Core.Abstractions.csprojGFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.csGFramework.Core/GFramework.Core.csprojGFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csprojGFramework.Core/Services/ServiceModuleManager.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.csGFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.csGFramework.csprojGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/Logging/TestLogger.csGFramework.Core.Abstractions/Cqrs/ICqrsRuntime.csGFramework.Cqrs.Abstractions/GlobalUsings.csGFramework.Core/Services/Modules/CqrsRuntimeModule.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Architectures/ArchitectureContext.csGFramework.Cqrs/GFramework.Cqrs.csproj
**/*.csproj
📄 CodeRabbit inference engine (AGENTS.md)
Follow repository defaults:
ImplicitUsingsdisabled,Nullableenabled,GenerateDocumentationFileenabled for shipped libraries,LangVersiongenerallypreview
Files:
GFramework.Core.Abstractions/GFramework.Core.Abstractions.csprojGFramework.Core/GFramework.Core.csprojGFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csprojGFramework.csprojGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs/GFramework.Cqrs.csproj
**/*.Tests/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.Tests/*.cs: When a public API defines multiple contract branches, tests MUST cover meaningful variants including null, empty, default, and filtered inputs when those branches change behavior
Regression fixes should include a test that fails before the fix and passes after it
Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant:ArchitectureTestsBase<T>,SyncTestArchitecture,AsyncTestArchitecture
Keep tests focused on observable behavior, not implementation trivia
Source generator changes MUST be covered by generator tests; preserve snapshot-based verification patterns already used in the repository
When generator behavior changes intentionally, update snapshots together with the implementation
Files:
GFramework.Cqrs.Tests/GlobalUsings.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/CqrsTestRuntime.cs
🧠 Learnings (22)
📚 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.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.csGFramework.Cqrs.Abstractions/Cqrs/IInput.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.csGFramework.Core/Services/ServiceModuleManager.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.csGFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.csGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/Logging/TestLogger.csGFramework.Core.Abstractions/Cqrs/ICqrsRuntime.csGFramework.Cqrs.Abstractions/GlobalUsings.csGFramework.Core/Services/Modules/CqrsRuntimeModule.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Architectures/ArchitectureContext.cs
📚 Learning: 2026-04-06T12:45:47.739Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:47.739Z
Learning: In the GFramework repository (GeWuYou/GFramework), even though `ImplicitUsings` is disabled in the `.csproj` files, the project uses a manual `GlobalUsings.cs` file with `global using` directives to provide common System namespaces (e.g., System, System.Threading, System.Threading.Tasks) project-wide. Do not flag missing System-level `using` imports in C# files within this repository, as they are covered by GlobalUsings.cs.
Applied to files:
GFramework.Core.Abstractions/GFramework.Core.Abstractions.csprojGFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.Core/GFramework.Core.csprojGFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csprojGFramework.slnGFramework.csprojGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs/GFramework.Cqrs.csproj
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : If a framework abstraction changes meaning or intended usage, update the explanatory comments in code as part of the same change
Applied to files:
GFramework.Core.Abstractions/GFramework.Core.Abstractions.csprojGFramework.Core/GFramework.Core.csprojGFramework.sln
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.csproj : Follow repository defaults: `ImplicitUsings` disabled, `Nullable` enabled, `GenerateDocumentationFile` enabled for shipped libraries, `LangVersion` generally `preview`
Applied to files:
GFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.Core/GFramework.Core.csprojGFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csprojGFramework.slnGFramework.csprojGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs.Abstractions/GlobalUsings.csGFramework.Cqrs/GFramework.Cqrs.csproj
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*SourceGenerators/**/*.cs : Keep source generators deterministic and free of hidden environment or network dependencies
Applied to files:
GFramework.Cqrs.Abstractions/Directory.Build.props
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.csprojGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Cqrs.Tests/CqrsTestRuntime.cs.github/workflows/ci.yml
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Source generator changes MUST be covered by generator tests; preserve snapshot-based verification patterns already used in the repository
Applied to files:
GFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.csprojGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs.github/workflows/ci.yml
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs
Applied to files:
GFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Treat `Meziantou.Analyzer` feedback and SonarQube maintainability rules as part of the coding standard
Applied to files:
GFramework.Cqrs.Abstractions/Directory.Build.props
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Use the namespace pattern `GFramework.{Module}.{Feature}` with PascalCase segments
Applied to files:
GFramework.Core/GFramework.Core.csprojGFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csprojGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.slnGFramework.csprojGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Abstractions/GlobalUsings.csGFramework.Core/Architectures/ArchitectureContext.csGFramework.Cqrs/GFramework.Cqrs.csproj
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions, and design rationale
Applied to files:
GFramework.Core/Services/ServiceModuleManager.csGFramework.Core/Architectures/ArchitectureContext.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use IServiceModule pattern to register built-in services (EventBus, CommandExecutor, QueryExecutor) with Architecture
Applied to files:
GFramework.Core/Services/ServiceModuleManager.csGFramework.Core/Services/Modules/CqrsRuntimeModule.csGFramework.Core/Architectures/ArchitectureContext.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use MicrosoftDiContainer wrapping Microsoft.Extensions.DependencyInjection for unified component registration and service resolution
Applied to files:
GFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core.Tests/CqrsTestRuntime.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Mirror the source structure in test projects whenever practical
Applied to files:
GFramework.slnGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation
Applied to files:
GFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs.github/workflows/ci.yml
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Do not rely on implicit imports; declare every required `using` explicitly in C# files
Applied to files:
GFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Abstractions/GlobalUsings.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Keep tests focused on observable behavior, not implementation trivia
Applied to files:
GFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Reuse existing architecture test infrastructure when relevant: `ArchitectureTestsBase<T>`, `SyncTestArchitecture`, `AsyncTestArchitecture`
Applied to files:
GFramework.Cqrs.Tests/GlobalUsings.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core/Architectures/ArchitectureContext.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.{cs,csproj} : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Applied to files:
GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj.github/workflows/ci.yml
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: IContextAware must provide unified context access through SetContext(IArchitectureContext) method for components to obtain architecture context
Applied to files:
GFramework.Core/Cqrs/Internal/CqrsDispatcher.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Implement CQRS pattern (Command Query Responsibility Segregation) with support for both synchronous and asynchronous execution, using Mediator pattern integrated via source code generators
Applied to files:
GFramework.Core/Architectures/ArchitectureContext.cs
🪛 GitHub Check: Build and Test
GFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.cs
[failure] 24-24:
The type or namespace name 'INotificationHandler<>' could not be found (are you missing a using directive or an assembly reference?)
[failure] 19-19:
The type or namespace name 'INotification' could not be found (are you missing a using directive or an assembly reference?)
[failure] 24-24:
The type or namespace name 'INotificationHandler<>' could not be found (are you missing a using directive or an assembly reference?)
[failure] 19-19:
The type or namespace name 'INotification' could not be found (are you missing a using directive or an assembly reference?)
🔇 Additional comments (32)
GFramework.Cqrs.Abstractions/Cqrs/IInput.cs (1)
20-20: 该变更保持接口语义稳定,符合预期。此处仅为格式层调整,不影响
IInput的公开 API 与行为。GFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.cs (1)
6-6: 查询输入接口变更安全,未引入行为风险。该段保持原有契约不变,可直接接受。
GFramework.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.cs (1)
20-20: 通知输入接口保持兼容,改动可接受。该变更未改变公开契约,风险很低。
GFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.cs (1)
20-20: 请求输入接口契约未变,改动合理。当前修改不影响调用方行为。
GFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.cs (1)
7-7: 命令输入接口改动无行为影响,符合预期。该段可直接合并。
GFramework.csproj (1)
66-68: CQRS 目录排除规则补齐完整,符合元包目标。
None/Compile/EmbeddedResource三类项同步排除,能避免新增目录被默认规则误包含。Also applies to: 110-112, 140-142
.github/workflows/ci.yml (1)
169-174: 已将 CQRS 测试接入 CI,并行执行策略一致。TRX 文件命名与结果目录策略保持统一,这个补充很有价值。
GFramework.Core.Abstractions/Cqrs/ICqrsRuntime.cs (1)
1-51: LGTM! 接口设计清晰,文档完整。
ICqrsRuntime接口很好地将请求分发、通知发布和流式处理抽象出来,使IArchitectureContext不再直接依赖具体的 runtime 实现。使用ValueTask和IAsyncEnumerable是合适的性能优化选择。GFramework.Cqrs.Abstractions/GlobalUsings.cs (1)
1-3: LGTM!全局 using 声明与项目既有模式一致,为 CQRS 抽象层提供必要的 BCL 类型支持。
GFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.cs (1)
1-17: LGTM! 单一职责接口设计良好。
ICqrsHandlerRegistrar提供了清晰的处理器注册抽象,使容器和架构启动链不再直接依赖具体的注册实现。GFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.cs (1)
1-27: LGTM! 适配器模式实现正确。
DefaultCqrsHandlerRegistrar正确地将ICqrsHandlerRegistrar接口委托给现有的CqrsHandlerRegistrar.RegisterHandlers静态方法,保持了空值检查的一致性。GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj (1)
20-22: LGTM!添加对
GFramework.Cqrs.Abstractions的项目引用是必要的,使ICqrsRuntime能够引用IRequest<TResponse>、INotification和IStreamRequest<TResponse>类型。GFramework.Core/GFramework.Core.csproj (1)
12-12: LGTM!添加对
GFramework.Cqrs.Abstractions的引用使GFramework.Core能够实现ICqrsRuntime和ICqrsHandlerRegistrar接口。GFramework.Core/Services/ServiceModuleManager.cs (1)
45-46: LGTM! 文档和模块注册都已正确更新。
CqrsRuntimeModule被正确添加到内置模块列表中,文档也已更新以反映 CQRS runtime 的加入。模块的优先级(15)确保它在基础总线模块之后、用户初始化之前注册。Also applies to: 60-60
GFramework.sln (1)
41-46: LGTM!新增的三个 CQRS 项目(Abstractions、实现、测试)已正确添加到解决方案中,项目 GUID 与配置条目一致,配置映射遵循现有模式。
Also applies to: 285-320
GFramework.Core/Ioc/MicrosoftDiContainer.cs (2)
458-477: LGTM!新增的
ResolveCqrsHandlerRegistrar()方法实现了良好的解耦设计:
- 从服务描述符中读取
ICqrsHandlerRegistrar实例,避免在容器冻结前依赖完整的服务提供者- 提供了清晰的错误消息,指导开发者确保 CQRS runtime 模块已正确安装
- 方法在写锁内调用,线程安全得到保障
426-427: LGTM!将直接调用静态方法改为通过抽象接口调用,符合依赖倒置原则,便于测试和扩展。
GFramework.Cqrs.Tests/GlobalUsings.cs (1)
1-26: LGTM!
GlobalUsings.cs遵循仓库约定,为测试项目提供了合适的全局命名空间导入,包括常用的 System 命名空间和测试框架依赖。GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs (2)
34-35: LGTM!在
SetUp中调用CqrsTestRuntime.RegisterInfrastructure(_container)是必要的,确保了ICqrsHandlerRegistrar在测试执行前已注册到容器中,与新的 CQRS 运行时架构保持一致。
316-340: LGTM!去重测试已正确更新:
- 使用
DeterministicOrderNotification替代原有的测试类型,与ContainerRegistrationFixtures.cs中定义的夹具对齐Clear()后重新注册基础设施的逻辑符合新架构要求- 测试验证了程序集去重状态在
Clear()后被正确重置GFramework.Cqrs.Tests/Logging/TestLogger.cs (1)
22-56: LGTM!
TestLogger实现简洁有效:
- 继承
AbstractLogger提供最小化的测试日志实现List<LogEntry>便于断言验证- XML 文档完整覆盖类、构造函数、属性和方法
GFramework.Cqrs/GFramework.Cqrs.csproj (1)
3-10: 无需操作。LangVersion属性已在Directory.Build.props中统一定义为preview,该文件通过继承获得此设置。当前.csproj文件已满足所有仓库编码规范。> Likely an incorrect or invalid review comment.GFramework.Cqrs.Abstractions/GFramework.Cqrs.Abstractions.csproj (1)
1-11: 该项目配置遵循仓库约定,无需修改。此文件属于 Abstractions 层项目,其配置正确地继承了
GFramework.Cqrs.Abstractions/Directory.Build.props中定义的属性,包括TargetFramework(netstandard2.1)和LangVersion(preview)。同一层级的其他 Abstractions 项目(如 GFramework.Core.Abstractions)采用相同的配置模式。非 Abstractions 项目才会在.csproj文件中显式声明TargetFrameworks和ImplicitUsings。GFramework.Core.Tests/CqrsTestRuntime.cs (2)
81-99: LGTM!
RegisterInfrastructure方法实现清晰,正确地通过反射实例化内部 CQRS 运行时组件并注册到容器中,与生产环境的CqrsRuntimeModule保持一致的注册模式。
106-117: LGTM!
RegisterHandlers方法现在正确地在注册处理器之前调用RegisterInfrastructure,确保ICqrsRuntime和ICqrsHandlerRegistrar已就绪,与生产启动路径保持一致。GFramework.Core/Services/Modules/CqrsRuntimeModule.cs (1)
1-61: LGTM!新增的
CqrsRuntimeModule正确实现了IServiceModule接口,将ICqrsRuntime和ICqrsHandlerRegistrar注册到 DI 容器中。模块优先级设置为 15,确保在基础服务模块之后、用户初始化之前完成注册。实现简洁,符合框架的服务模块模式。Based on learnings: "Use IServiceModule pattern to register built-in services (EventBus, CommandExecutor, QueryExecutor) with Architecture"GFramework.Core/Cqrs/Internal/CqrsDispatcher.cs (4)
15-17: LGTM!构造函数签名简化为
(IIocContainer, ILogger),移除了对IArchitectureContext的构造时依赖。现在正确实现ICqrsRuntime接口,支持通过方法参数传递上下文,实现了调度器与上下文的解耦。
30-65: LGTM!
PublishAsync方法重构正确:
- 接收
IArchitectureContext参数并验证非空- 通过
PrepareHandler(handler, context)为处理器注入上下文- 保持了通知分发的并发安全性(使用
ConcurrentDictionary缓存委托)
75-112: LGTM!
SendAsync方法正确处理了上下文传递,包括对处理器和所有管道行为的上下文注入。请求/管道调用器缓存模式保持不变,性能优化得以保留。
145-154: LGTM!
PrepareHandler改为static方法是正确的重构——该方法不依赖实例状态,仅操作传入的参数。通过参数传递context替代捕获实例字段,使方法更纯粹且易于测试。GFramework.Core/Architectures/ArchitectureContext.cs (2)
66-72: LGTM!CQRS 方法(
SendRequestAsync、PublishAsync、CreateStream)正确委托给ICqrsRuntime,并将this作为上下文参数传递,使处理器能够访问完整的架构上下文。这种设计实现了运行时分发与上下文的解耦,符合 CQRS 架构解耦的目标。Based on learnings: "Implement CQRS pattern (Command Query Responsibility Segregation) with support for both synchronous and asynchronous execution"Also applies to: 92-99, 108-114
149-149: LGTM!参数类型更新为使用
Abstractions.Cqrs.Query.IQuery<T>和Abstractions.Cqrs.Command.ICommand<T>,保持了与新 CQRS 抽象层的一致性。方法重载通过完全限定名消除了与传统IQuery/ICommand接口的歧义。Also applies to: 163-163, 189-189, 325-325, 364-364, 386-386
- 将 Meziantou.Analyzer 从 2.0.264 版本升级到 3.0.46 版本 - 将 Meziantou.Polyfill 从 1.0.71 版本升级到 1.0.109 版本
- 移除了 GFramework.Cqrs.Tests 项目的 WarningLevel 配置 - 使测试项目遵循默认警告级别设置
- 验证通知处理器按稳定名称顺序执行而非依赖反射枚举顺序 - 测试部分类型加载失败时保留可加载类型并记录诊断日志 - 验证源码生成注册器优先级高于反射扫描机制 - 测试生成注册器元数据损坏时回退到反射扫描路径 - 实现确定性通知处理器执行顺序验证功能 - 添加捕获型日志工厂提供程序用于测试断言 - 修正命名空间从Core.Tests.Logging到Cqrs.Tests.Logging
- 修正Core模块命名空间 - 修正Godot模块命名空间
- 添加GFramework.Core.Coroutine.Extensions命名空间引用 - 保持现有测试功能完整性 - 优化代码结构以匹配最新框架变更
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
GFramework.Core.Abstractions/Architectures/IArchitectureContext.cs (1)
17-19:⚠️ Potential issue | 🟡 MinorXML 说明仍包含旧 CQRS 命名空间,和新签名不一致。
接口签名已切换到
GFramework.Cqrs.Abstractions.Cqrs.*,但<remarks>仍写旧路径,建议同步更新,避免迁移误导。💡 建议修复
- /// <para>新的 <c>GFramework.Core.Abstractions.Cqrs</c> 契约由内置 CQRS dispatcher 统一处理,支持 request pipeline、notification publish 与 stream request。</para> + /// <para>新的 <c>GFramework.Cqrs.Abstractions.Cqrs</c> 契约由内置 CQRS dispatcher 统一处理,支持 request pipeline、notification publish 与 stream request。</para> @@ - /// 这是迁移后的推荐查询入口。新查询应优先实现 <c>GFramework.Core.Abstractions.Cqrs.Query.IQuery<TResponse></c>。 + /// 这是迁移后的推荐查询入口。新查询应优先实现 <c>GFramework.Cqrs.Abstractions.Cqrs.Query.IQuery<TResponse></c>。As per coding guidelines: "Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs".
Also applies to: 177-180
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core.Abstractions/Architectures/IArchitectureContext.cs` around lines 17 - 19, Update the XML documentation remarks on the IArchitectureContext interface to reference the new CQRS namespace and method signatures: replace old occurrences of GFramework.Core.Abstractions.Command and GFramework.Core.Abstractions.Query with GFramework.Cqrs.Abstractions.Cqrs (or the exact new namespaces used by the SendRequestAsync{TResponse}(IRequest{TResponse},CancellationToken) and SendAsync{TCommand}(TCommand,CancellationToken) overloads), and ensure the <remarks> text and any <see cref="..."/> tags point to the new SendRequestAsync{TResponse} and SendAsync{TCommand} members so the XML docs match the current public API.GFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.cs (1)
23-28:⚠️ Potential issue | 🟡 Minor弃用提示仍指向旧命名空间路径。
[Obsolete]文案还在指向GFramework.Core.Cqrs.Extensions.CqrsCoroutineExtensions,但当前实际扩展类型位于GFramework.Core.Coroutine.Extensions,会误导迁移方。💡 建议修复
[Obsolete( - "Use GFramework.Core.Cqrs.Extensions.CqrsCoroutineExtensions instead. This compatibility alias will be removed in a future major version.")] + "Use GFramework.Core.Coroutine.Extensions.CqrsCoroutineExtensions instead. This compatibility alias will be removed in a future major version.")]As per coding guidelines: "Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.cs` around lines 23 - 28, Update the XML docs and Obsolete attribute text on the MediatorCoroutineExtensions compatibility type to point to the actual new location: replace the cref and the string in [Obsolete(...)] so they reference GFramework.Core.Coroutine.Extensions.CqrsCoroutineExtensions (not GFramework.Core.Cqrs.Extensions.CqrsCoroutineExtensions); edit the XML summary line containing <see cref="CqrsCoroutineExtensions" /> and the Obsolete message on the MediatorCoroutineExtensions type to use the correct fully-qualified namespace, keeping EditorBrowsable(EditorBrowsableState.Never) unchanged.GFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs (1)
13-15:⚠️ Potential issue | 🟡 Minor
Obsolete文案需要同步到当前扩展类命名空间。Line 14 仍使用旧路径
GFramework.Core.Cqrs.Extensions...,建议改为当前GFramework.Core.Extensions.ContextAwareCqrsQueryExtensions。🩹 建议修复
[Obsolete( - "Use GFramework.Core.Cqrs.Extensions.ContextAwareCqrsQueryExtensions instead. This compatibility alias will be removed in a future major version.")] + "Use GFramework.Core.Extensions.ContextAwareCqrsQueryExtensions instead. This compatibility alias will be removed in a future major version.")]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs` around lines 13 - 15, Update the Obsolete attribute message on the ContextAwareMediatorQueryExtensions class so the recommended type uses the current namespace and class name: replace "GFramework.Core.Cqrs.Extensions.ContextAwareCqrsQueryExtensions" with "GFramework.Core.Extensions.ContextAwareCqrsQueryExtensions" in the Obsolete(...) string for the ContextAwareMediatorQueryExtensions class to keep the deprecation message accurate.GFramework.Core/Extensions/ContextAwareMediatorExtensions.cs (1)
13-15:⚠️ Potential issue | 🟡 Minor修正
Obsolete提示中的过时命名空间。Line 14 仍指向
GFramework.Core.Cqrs.Extensions.ContextAwareCqrsExtensions,与当前实际入口不一致,会误导迁移调用方。🩹 建议修复
[Obsolete( - "Use GFramework.Core.Cqrs.Extensions.ContextAwareCqrsExtensions instead. This compatibility alias will be removed in a future major version.")] + "Use GFramework.Core.Extensions.ContextAwareCqrsExtensions instead. This compatibility alias will be removed in a future major version.")]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core/Extensions/ContextAwareMediatorExtensions.cs` around lines 13 - 15, The Obsolete attribute on the ContextAwareMediatorExtensions class still points to the wrong namespace; update the string literal in the Obsolete attribute applied to the ContextAwareMediatorExtensions class so it references the actual current compatibility alias/entry point (replace "GFramework.Core.Cqrs.Extensions.ContextAwareCqrsExtensions" with the correct fully-qualified type name used today), ensuring the message reads like "Use <Correct.Namespace.TypeName> instead. This compatibility alias will be removed in a future major version."; modify the Obsolete attribute text where it appears on the ContextAwareMediatorExtensions class.
🧹 Nitpick comments (2)
GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs (1)
180-200:InvocationCount在并行测试下存在竞态,建议改为原子计数。Line 199 的
InvocationCount++非原子操作,可能导致偶发断言不稳定。♻️ 建议修复
public sealed class TrackingPipelineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse> { + private static int _invocationCount; + /// <summary> /// 获取当前测试进程中该请求类型对应的行为触发次数。 /// </summary> - public static int InvocationCount { get; set; } + public static int InvocationCount + { + get => Volatile.Read(ref _invocationCount); + set => Volatile.Write(ref _invocationCount, value); + } @@ public async ValueTask<TResponse> Handle( TRequest message, MessageHandlerDelegate<TRequest, TResponse> next, CancellationToken cancellationToken) { - InvocationCount++; + Interlocked.Increment(ref _invocationCount); return await next(message, cancellationToken); } }As per coding guidelines: Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs` around lines 180 - 200, The static InvocationCount on TrackingPipelineBehavior is incremented non-atomically in Handle (InvocationCount++), causing race conditions in parallel tests; change InvocationCount to a static int and update the increment in Handle to use System.Threading.Interlocked.Increment(ref InvocationCount) so increments are atomic and deterministic when multiple threads invoke TrackingPipelineBehavior.Handle concurrently.GFramework.Core.Tests/CqrsTestRuntime.cs (1)
88-113: 避免RegisterHandlers引入隐式重复注册副作用。Line 112 在扫描处理器前总是再次注册基础设施;当测试已显式注入 runtime/registrar 时,这会造成覆盖或重复注册,降低测试可控性。建议让基础设施注册幂等化。
♻️ 建议改为幂等注册
internal static void RegisterInfrastructure(MicrosoftDiContainer container) { ArgumentNullException.ThrowIfNull(container); - var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher"); - var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(CqrsTestRuntime)); - var runtime = (ICqrsRuntime)CqrsDispatcherConstructor.Invoke([container, runtimeLogger]); - var registrar = - (ICqrsHandlerRegistrar)DefaultCqrsHandlerRegistrarConstructor.Invoke([container, registrarLogger]); - - container.Register<ICqrsRuntime>(runtime); - container.Register<ICqrsHandlerRegistrar>(registrar); + if (container.Get<ICqrsRuntime>() is null) + { + var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher"); + var runtime = (ICqrsRuntime)CqrsDispatcherConstructor.Invoke([container, runtimeLogger]); + container.Register<ICqrsRuntime>(runtime); + } + + if (container.Get<ICqrsHandlerRegistrar>() is null) + { + var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(CqrsTestRuntime)); + var registrar = + (ICqrsHandlerRegistrar)DefaultCqrsHandlerRegistrarConstructor.Invoke([container, registrarLogger]); + container.Register<ICqrsHandlerRegistrar>(registrar); + } }As per coding guidelines: Avoid hidden side effects in property getters, constructors, and registration helpers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core.Tests/CqrsTestRuntime.cs` around lines 88 - 113, RegisterHandlers currently always calls RegisterInfrastructure which can overwrite explicit test registrations; make the registration idempotent by changing RegisterInfrastructure (or its use in RegisterHandlers) to check for existing registrations before registering runtime/registrar: detect whether ICqrsRuntime and ICqrsHandlerRegistrar are already registered in the MicrosoftDiContainer (or provide a RegisterIfNotExists helper) and only invoke CqrsDispatcherConstructor/DefaultCqrsHandlerRegistrarConstructor and call container.Register when not already present, keeping the same logger creation and types (ICqrsRuntime, ICqrsHandlerRegistrar, RegisterInfrastructure, RegisterHandlers, CqrsTestRuntime) to avoid hidden duplicate registrations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs`:
- Around line 362-383: 这几个公共 CQRS 方法缺少 XML 文档注释:为 SendCommandAsync, SendCommand,
SendQueryAsync, SendQuery 四个方法补齐 /// 注释,包含 <summary> 描述方法用途、<param name="..."> 为
command/query 和 CancellationToken 提供说明、<returns>
说明返回类型(ValueTask<TResponse>/TResponse)、在可能抛出异常时添加 <exception>(例如
ArgumentNullException)并在需要时加入 <remarks> 提示行为或线程/同步注意事项;确保注释风格和项目其他文档一致并覆盖所有公共签名。
In `@GFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.cs`:
- Around line 4-6: The Obsolete attribute message still points to the old
namespace; update the string to reference the new namespace
"GFramework.Core.Coroutine.Extensions". Locate the Obsolete on the
CqrsCoroutineExtensions declaration (and any related alias or
MediatorCoroutineExtensions references) and change the message text from "Use
GFramework.Core.Cqrs.Extensions.CqrsCoroutineExtensions instead..." to "Use
GFramework.Core.Coroutine.Extensions.CqrsCoroutineExtensions instead..." so the
deprecation guidance matches the migrated namespace.
In `@GFramework.Core/Cqrs/Internal/CqrsDispatcher.cs`:
- Around line 20-29:
为四个进程级静态缓存字段(RequestInvokers、RequestPipelineInvokers、NotificationInvokers、StreamInvokers)在声明处添加简短内联注释,说明它们是进程范围的共享
ConcurrentDictionary、基于线程安全的并发访问假设(使用 ConcurrentDictionary
保证并发读写安全)、生命周期(随进程存活且不主动释放)、潜在增长边界和故障模式(当前为无界缓存,可能导致内存增长,应监控大小/引入上限或清理策略),并注明若将来需要回收或度量应替换为有界缓存或统计/指标采集点;确保注释清晰引用这些字段名以便日后维护。
In `@GFramework.Core/Extensions/ContextAwareCqrsExtensions.cs`:
- Around line 2-4: Update the obsolete compatibility messages and related test
assertions to point to the new namespace "GFramework.Core.Extensions.*": in the
compatibility alias classes ContextAwareMediatorExtensions,
ContextAwareMediatorCommandExtensions, ContextAwareMediatorQueryExtensions and
MediatorCoroutineExtensions, replace any Obsolete message text referencing
"GFramework.Core.Cqrs.Extensions.*" with "GFramework.Core.Extensions.*"; then
update the assertions in MediatorCompatibilityDeprecationTests to expect the new
namespace path in the deprecation message checks. Ensure you only change the
string content of the Obsolete messages and test expectations, keeping the
Obsolete attributes and compatibility aliases otherwise intact.
In
`@GFramework.Godot.SourceGenerators.Abstractions/UI/AutoRegisterExportedCollectionsAttribute.cs`:
- Line 1: The metadata type strings used to match attributes are missing the
".UI" segment; update the metadata name constants in the generators so they
match the moved attributes. In the AutoRegisterExportedCollectionsGenerator,
AutoUiPageGenerator, and AutoSceneGenerator classes, locate the metadata name
constructions that use GodotSourceGeneratorsAbstractionsPath and append ".UI" to
the path (i.e., change the metadata constants built from
GodotSourceGeneratorsAbstractionsPath +
".AutoRegisterExportedCollectionsAttribute"/".AutoUiPageAttribute"/".AutoSceneAttribute"
to include ".UI" before the attribute type); ensure all four metadata constants
are updated so the generators can find the attributes in the
GFramework.Godot.SourceGenerators.Abstractions.UI namespace.
In `@GFramework.Godot.SourceGenerators.Abstractions/UI/AutoSceneAttribute.cs`:
- Line 1: The generator still looks up the old attribute type name; update the
metadata reference in AutoSceneGenerator so it uses the new fully-qualified name
that includes the .UI namespace. Specifically, in
GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator (the code that
calls Compilation.GetTypeByMetadataName or otherwise checks for
"GFramework.Godot.SourceGenerators.Abstractions.AutoSceneAttribute"), replace
that string with the new
"GFramework.Godot.SourceGenerators.Abstractions.UI.AutoSceneAttribute" (and
adjust any related symbol comparisons to reference the AutoSceneAttribute type).
Ensure any tests or helper methods that reference the old symbol name are
updated accordingly.
In `@GFramework.Godot.SourceGenerators.Abstractions/UI/AutoUiPageAttribute.cs`:
- Line 1: 生成器使用的类型查找常量未随 AutoUiPageAttribute 的命名空间迁移到 .UI 而更新,导致
AutoUiPageGenerator 找不到类型并跳过页面样板生成;请在 AutoUiPageGenerator(引用
PathContests.GodotSourceGeneratorsAbstractionsPath 的地方)把目标类型名称更新为包含 .UI(例如将
$"{PathContests.GodotSourceGeneratorsAbstractionsPath}.AutoUiPageAttribute" 改为
包含 ".UI.AutoUiPageAttribute" 的对应字符串),或者把 PathContests 常量调整为包括 .UI,从而确保
AutoUiPageAttribute 能被正确识别并生成页面代码。
---
Outside diff comments:
In `@GFramework.Core.Abstractions/Architectures/IArchitectureContext.cs`:
- Around line 17-19: Update the XML documentation remarks on the
IArchitectureContext interface to reference the new CQRS namespace and method
signatures: replace old occurrences of GFramework.Core.Abstractions.Command and
GFramework.Core.Abstractions.Query with GFramework.Cqrs.Abstractions.Cqrs (or
the exact new namespaces used by the
SendRequestAsync{TResponse}(IRequest{TResponse},CancellationToken) and
SendAsync{TCommand}(TCommand,CancellationToken) overloads), and ensure the
<remarks> text and any <see cref="..."/> tags point to the new
SendRequestAsync{TResponse} and SendAsync{TCommand} members so the XML docs
match the current public API.
In `@GFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.cs`:
- Around line 23-28: Update the XML docs and Obsolete attribute text on the
MediatorCoroutineExtensions compatibility type to point to the actual new
location: replace the cref and the string in [Obsolete(...)] so they reference
GFramework.Core.Coroutine.Extensions.CqrsCoroutineExtensions (not
GFramework.Core.Cqrs.Extensions.CqrsCoroutineExtensions); edit the XML summary
line containing <see cref="CqrsCoroutineExtensions" /> and the Obsolete message
on the MediatorCoroutineExtensions type to use the correct fully-qualified
namespace, keeping EditorBrowsable(EditorBrowsableState.Never) unchanged.
In `@GFramework.Core/Extensions/ContextAwareMediatorExtensions.cs`:
- Around line 13-15: The Obsolete attribute on the
ContextAwareMediatorExtensions class still points to the wrong namespace; update
the string literal in the Obsolete attribute applied to the
ContextAwareMediatorExtensions class so it references the actual current
compatibility alias/entry point (replace
"GFramework.Core.Cqrs.Extensions.ContextAwareCqrsExtensions" with the correct
fully-qualified type name used today), ensuring the message reads like "Use
<Correct.Namespace.TypeName> instead. This compatibility alias will be removed
in a future major version."; modify the Obsolete attribute text where it appears
on the ContextAwareMediatorExtensions class.
In `@GFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs`:
- Around line 13-15: Update the Obsolete attribute message on the
ContextAwareMediatorQueryExtensions class so the recommended type uses the
current namespace and class name: replace
"GFramework.Core.Cqrs.Extensions.ContextAwareCqrsQueryExtensions" with
"GFramework.Core.Extensions.ContextAwareCqrsQueryExtensions" in the
Obsolete(...) string for the ContextAwareMediatorQueryExtensions class to keep
the deprecation message accurate.
---
Nitpick comments:
In `@GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs`:
- Around line 180-200: The static InvocationCount on TrackingPipelineBehavior is
incremented non-atomically in Handle (InvocationCount++), causing race
conditions in parallel tests; change InvocationCount to a static int and update
the increment in Handle to use System.Threading.Interlocked.Increment(ref
InvocationCount) so increments are atomic and deterministic when multiple
threads invoke TrackingPipelineBehavior.Handle concurrently.
In `@GFramework.Core.Tests/CqrsTestRuntime.cs`:
- Around line 88-113: RegisterHandlers currently always calls
RegisterInfrastructure which can overwrite explicit test registrations; make the
registration idempotent by changing RegisterInfrastructure (or its use in
RegisterHandlers) to check for existing registrations before registering
runtime/registrar: detect whether ICqrsRuntime and ICqrsHandlerRegistrar are
already registered in the MicrosoftDiContainer (or provide a RegisterIfNotExists
helper) and only invoke
CqrsDispatcherConstructor/DefaultCqrsHandlerRegistrarConstructor and call
container.Register when not already present, keeping the same logger creation
and types (ICqrsRuntime, ICqrsHandlerRegistrar, RegisterInfrastructure,
RegisterHandlers, CqrsTestRuntime) to avoid hidden duplicate registrations.
🪄 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: 568582e4-aa87-437d-8f84-a1d8343c66a1
📒 Files selected for processing (80)
GFramework.Core.Abstractions/Architectures/IArchitectureContext.csGFramework.Core.Abstractions/Cqrs/ICqrsRuntime.csGFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Tests/Architectures/GameContextTests.csGFramework.Core.Tests/Command/AbstractAsyncCommandTests.csGFramework.Core.Tests/Command/CommandExecutorTests.csGFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core.Tests/Query/AbstractAsyncQueryTests.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Core/Architectures/ArchitectureContext.csGFramework.Core/Command/AbstractAsyncCommandWithInput.csGFramework.Core/Command/AbstractAsyncCommandWithResult.csGFramework.Core/Command/AbstractCommandWithInput.csGFramework.Core/Command/AbstractCommandWithResult.csGFramework.Core/Command/EmptyCommandInput.csGFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.csGFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.csGFramework.Core/Cqrs/Behaviors/LoggingBehavior.csGFramework.Core/Cqrs/Behaviors/PerformanceBehavior.csGFramework.Core/Cqrs/Command/AbstractCommandHandler.csGFramework.Core/Cqrs/Command/AbstractStreamCommandHandler.csGFramework.Core/Cqrs/Command/CommandBase.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Cqrs/Internal/CqrsHandlerRegistrar.csGFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.csGFramework.Core/Cqrs/Notification/AbstractNotificationHandler.csGFramework.Core/Cqrs/Notification/NotificationBase.csGFramework.Core/Cqrs/Query/AbstractQueryHandler.csGFramework.Core/Cqrs/Query/AbstractStreamQueryHandler.csGFramework.Core/Cqrs/Query/QueryBase.csGFramework.Core/Cqrs/Request/AbstractRequestHandler.csGFramework.Core/Cqrs/Request/AbstractStreamRequestHandler.csGFramework.Core/Cqrs/Request/RequestBase.csGFramework.Core/Extensions/ContextAwareCqrsCommandExtensions.csGFramework.Core/Extensions/ContextAwareCqrsExtensions.csGFramework.Core/Extensions/ContextAwareCqrsQueryExtensions.csGFramework.Core/Extensions/ContextAwareMediatorCommandExtensions.csGFramework.Core/Extensions/ContextAwareMediatorExtensions.csGFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Core/Query/AbstractAsyncQueryWithResult.csGFramework.Core/Query/AbstractQueryWithResult.csGFramework.Core/Query/EmptyQueryInput.csGFramework.Core/Services/Modules/CqrsRuntimeModule.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommand.csGFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.csGFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.csGFramework.Cqrs.Abstractions/Cqrs/IInput.csGFramework.Cqrs.Abstractions/Cqrs/INotification.csGFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.csGFramework.Cqrs.Abstractions/Cqrs/IPipelineBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IRequest.csGFramework.Cqrs.Abstractions/Cqrs/IRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequest.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/MessageHandlerDelegate.csGFramework.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQuery.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Cqrs.Abstractions/Cqrs/Unit.csGFramework.Cqrs.Abstractions/Directory.Build.propsGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs.Tests/Logging/TestLogger.csGFramework.Cqrs.Tests/Mediator/MediatorAdvancedFeaturesTests.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Cqrs.Tests/Mediator/MediatorComprehensiveTests.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoRegisterExportedCollectionsAttribute.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoSceneAttribute.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoUiPageAttribute.csGFramework.Godot.SourceGenerators.Abstractions/UI/RegisterExportedCollectionAttribute.csGFramework.Godot/Coroutine/ContextAwareCoroutineExtensions.cs
✅ Files skipped from review due to trivial changes (32)
- GFramework.Core/Cqrs/Notification/AbstractNotificationHandler.cs
- GFramework.Core/Cqrs/Request/AbstractRequestHandler.cs
- GFramework.Core.Tests/Command/AbstractAsyncCommandTests.cs
- GFramework.Core/Cqrs/Internal/CqrsHandlerRegistrar.cs
- GFramework.Core.Tests/Command/CommandExecutorTests.cs
- GFramework.Core/Cqrs/Query/AbstractStreamQueryHandler.cs
- GFramework.Cqrs.Abstractions/Cqrs/IRequestHandler.cs
- GFramework.Core.Tests/Query/AbstractAsyncQueryTests.cs
- GFramework.Cqrs.Abstractions/Cqrs/Unit.cs
- GFramework.Core/Cqrs/Command/AbstractCommandHandler.cs
- GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs
- GFramework.Core/Command/AbstractAsyncCommandWithResult.cs
- GFramework.Cqrs.Abstractions/Cqrs/IPipelineBehavior.cs
- GFramework.Cqrs.Tests/Mediator/MediatorAdvancedFeaturesTests.cs
- GFramework.Cqrs.Abstractions/Cqrs/Command/ICommand.cs
- GFramework.Core/Cqrs/Behaviors/PerformanceBehavior.cs
- GFramework.Godot.SourceGenerators.Abstractions/UI/RegisterExportedCollectionAttribute.cs
- GFramework.Core/Cqrs/Query/AbstractQueryHandler.cs
- GFramework.Core/Cqrs/Command/AbstractStreamCommandHandler.cs
- GFramework.Cqrs.Tests/Mediator/MediatorComprehensiveTests.cs
- GFramework.Cqrs.Abstractions/Directory.Build.props
- GFramework.Cqrs.Abstractions/Cqrs/MessageHandlerDelegate.cs
- GFramework.Core/Extensions/ContextAwareMediatorCommandExtensions.cs
- GFramework.Core/Cqrs/Behaviors/LoggingBehavior.cs
- GFramework.Godot/Coroutine/ContextAwareCoroutineExtensions.cs
- GFramework.Core/Cqrs/Request/RequestBase.cs
- GFramework.Core.Tests/Cqrs/ContainerRegistrationFixtures.cs
- GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj
- GFramework.Core/Cqrs/Internal/DefaultCqrsHandlerRegistrar.cs
- GFramework.Cqrs.Tests/Logging/TestLogger.cs
- GFramework.Core.Abstractions/Cqrs/ICqrsRuntime.cs
- GFramework.Core/Query/AbstractAsyncQueryWithResult.cs
🚧 Files skipped from review as they are similar to previous changes (10)
- GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs
- GFramework.Cqrs.Abstractions/Cqrs/Command/ICommandInput.cs
- GFramework.Cqrs.Abstractions/Cqrs/IInput.cs
- GFramework.Cqrs.Abstractions/Cqrs/ICqrsHandlerRegistrar.cs
- GFramework.Core/Ioc/MicrosoftDiContainer.cs
- GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs
- GFramework.Cqrs.Abstractions/Cqrs/Notification/INotificationInput.cs
- GFramework.Core/Services/Modules/CqrsRuntimeModule.cs
- GFramework.Cqrs.Abstractions/Cqrs/Query/IQueryInput.cs
- GFramework.Core/Architectures/ArchitectureContext.cs
📜 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). (2)
- GitHub Check: Analyze (C#)
- GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (3)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, and edge cases
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions, and design rationale
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions, and diagnostic or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every requiredusingexplicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, constants use PascalCase; interfaces useIprefix; parameters and locals use camelCase; private fields use_camelCase
Use 4 spaces for indentation (not tabs), use Allman braces, and keepusingdirectives at the top of the file sorted consistently
Prefer one primary type per file unless the surrounding project alread...
Files:
GFramework.Core/Command/AbstractAsyncCommandWithInput.csGFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/INotification.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequest.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoUiPageAttribute.csGFramework.Core/Cqrs/Query/QueryBase.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoRegisterExportedCollectionsAttribute.csGFramework.Core/Extensions/ContextAwareCqrsCommandExtensions.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Core/Command/EmptyCommandInput.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoSceneAttribute.csGFramework.Core/Query/EmptyQueryInput.csGFramework.Core/Cqrs/Command/CommandBase.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQuery.csGFramework.Core/Cqrs/Request/AbstractStreamRequestHandler.csGFramework.Core/Extensions/ContextAwareCqrsExtensions.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core/Extensions/ContextAwareMediatorExtensions.csGFramework.Core/Cqrs/Notification/NotificationBase.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.csGFramework.Core/Extensions/ContextAwareCqrsQueryExtensions.csGFramework.Core/Command/AbstractCommandWithInput.csGFramework.Core/Query/AbstractQueryWithResult.csGFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Core/Command/AbstractCommandWithResult.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Abstractions/Architectures/IArchitectureContext.csGFramework.Core.Tests/Architectures/GameContextTests.csGFramework.Cqrs.Abstractions/Cqrs/IRequest.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs
**/*.{cs,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Files:
GFramework.Core/Command/AbstractAsyncCommandWithInput.csGFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/INotification.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequest.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoUiPageAttribute.csGFramework.Core/Cqrs/Query/QueryBase.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoRegisterExportedCollectionsAttribute.csGFramework.Core/Extensions/ContextAwareCqrsCommandExtensions.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Core/Command/EmptyCommandInput.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoSceneAttribute.csGFramework.Core/Query/EmptyQueryInput.csGFramework.Core/Cqrs/Command/CommandBase.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQuery.csGFramework.Core/Cqrs/Request/AbstractStreamRequestHandler.csGFramework.Core/Extensions/ContextAwareCqrsExtensions.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core/Extensions/ContextAwareMediatorExtensions.csGFramework.Core/Cqrs/Notification/NotificationBase.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.csGFramework.Core/Extensions/ContextAwareCqrsQueryExtensions.csGFramework.Core/Command/AbstractCommandWithInput.csGFramework.Core/Query/AbstractQueryWithResult.csGFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Core/Command/AbstractCommandWithResult.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Abstractions/Architectures/IArchitectureContext.csGFramework.Core.Tests/Architectures/GameContextTests.csGFramework.Cqrs.Abstractions/Cqrs/IRequest.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs
**/*.Tests/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.Tests/*.cs: When a public API defines multiple contract branches, tests MUST cover meaningful variants including null, empty, default, and filtered inputs when those branches change behavior
Regression fixes should include a test that fails before the fix and passes after it
Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant:ArchitectureTestsBase<T>,SyncTestArchitecture,AsyncTestArchitecture
Keep tests focused on observable behavior, not implementation trivia
Source generator changes MUST be covered by generator tests; preserve snapshot-based verification patterns already used in the repository
When generator behavior changes intentionally, update snapshots together with the implementation
Files:
GFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/CqrsTestRuntime.cs
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use IServiceModule pattern to register built-in services (EventBus, CommandExecutor, QueryExecutor) with Architecture
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Implement CQRS pattern (Command Query Responsibility Segregation) with support for both synchronous and asynchronous execution, using Mediator pattern integrated via source code generators
Applied to files:
GFramework.Core/Command/AbstractAsyncCommandWithInput.csGFramework.Core/Command/EmptyCommandInput.csGFramework.Core/Query/EmptyQueryInput.csGFramework.Core/Cqrs/Command/CommandBase.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.csGFramework.Core/Command/AbstractCommandWithInput.csGFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.csGFramework.Core/Command/AbstractCommandWithResult.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Abstractions/Architectures/IArchitectureContext.csGFramework.Core.Tests/Architectures/GameContextTests.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.cs
📚 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/Command/AbstractAsyncCommandWithInput.csGFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequestHandler.csGFramework.Cqrs.Abstractions/Cqrs/INotification.csGFramework.Cqrs.Abstractions/Cqrs/IStreamRequest.csGFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoUiPageAttribute.csGFramework.Core/Cqrs/Query/QueryBase.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoRegisterExportedCollectionsAttribute.csGFramework.Core/Extensions/ContextAwareCqrsCommandExtensions.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Core/Command/EmptyCommandInput.csGFramework.Godot.SourceGenerators.Abstractions/UI/AutoSceneAttribute.csGFramework.Core/Query/EmptyQueryInput.csGFramework.Core/Cqrs/Command/CommandBase.csGFramework.Cqrs.Abstractions/Cqrs/Query/IQuery.csGFramework.Core/Cqrs/Request/AbstractStreamRequestHandler.csGFramework.Core/Extensions/ContextAwareCqrsExtensions.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core/Extensions/ContextAwareMediatorExtensions.csGFramework.Core/Cqrs/Notification/NotificationBase.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.csGFramework.Core/Extensions/ContextAwareCqrsQueryExtensions.csGFramework.Core/Command/AbstractCommandWithInput.csGFramework.Core/Query/AbstractQueryWithResult.csGFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Core/Command/AbstractCommandWithResult.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Abstractions/Architectures/IArchitectureContext.csGFramework.Core.Tests/Architectures/GameContextTests.csGFramework.Cqrs.Abstractions/Cqrs/IRequest.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Source generator changes MUST be covered by generator tests; preserve snapshot-based verification patterns already used in the repository
Applied to files:
GFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Core.Tests/Architectures/GameContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Tests/Architectures/GameContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Keep tests focused on observable behavior, not implementation trivia
Applied to files:
GFramework.Core.Tests/Query/QueryExecutorTests.csGFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core.Tests/Query/AsyncQueryExecutorTests.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Tests/Architectures/GameContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Use the namespace pattern `GFramework.{Module}.{Feature}` with PascalCase segments
Applied to files:
GFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.csGFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Tests/Architectures/GameContextTests.csGFramework.Cqrs.Abstractions/Cqrs/IRequest.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation
Applied to files:
GFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/GameContextTests.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Applies to **/*.cs : ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
Applied to files:
GFramework.Core/Extensions/ContextAwareCqrsExtensions.csGFramework.Core/Extensions/ContextAwareMediatorExtensions.csGFramework.Core/Extensions/ContextAwareCqrsQueryExtensions.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Reuse existing architecture test infrastructure when relevant: `ArchitectureTestsBase<T>`, `SyncTestArchitecture`, `AsyncTestArchitecture`
Applied to files:
GFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.csGFramework.Core.Tests/CqrsTestRuntime.csGFramework.Cqrs.Tests/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Tests/Architectures/GameContextTests.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use MicrosoftDiContainer wrapping Microsoft.Extensions.DependencyInjection for unified component registration and service resolution
Applied to files:
GFramework.Core.Tests/CqrsTestRuntime.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Avoid hidden side effects in property getters, constructors, and registration helpers
Applied to files:
GFramework.Cqrs.Tests/CqrsTestRuntime.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Do not rely on implicit imports; declare every required `using` explicitly in C# files
Applied to files:
GFramework.Cqrs.Tests/CqrsTestRuntime.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use IServiceModule pattern to register built-in services (EventBus, CommandExecutor, QueryExecutor) with Architecture
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Abstractions/Architectures/IArchitectureContext.csGFramework.Core.Tests/Architectures/GameContextTests.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: IContextAware must provide unified context access through SetContext(IArchitectureContext) method for components to obtain architecture context
Applied to files:
GFramework.Core/Cqrs/Internal/CqrsDispatcher.cs
🔇 Additional comments (30)
GFramework.Cqrs.Abstractions/Cqrs/INotificationHandler.cs (1)
1-1: 命名空间迁移保持一致且安全。该契约迁移到
GFramework.Cqrs.Abstractions.Cqrs后接口语义与调用面未变化,符合本次 CQRS 抽象解耦目标。GFramework.Core/Query/EmptyQueryInput.cs (1)
1-1:EmptyQueryInput的接口迁移正确。占位输入类型继续实现查询输入契约,仅切换到新抽象命名空间,改动清晰。
Also applies to: 11-11
GFramework.Cqrs.Tests/Mediator/MediatorArchitectureIntegrationTests.cs (2)
7-10: 测试命名空间与 CQRS 抽象引用已对齐。该调整与新
GFramework.Cqrs.Abstractions体系一致,测试归属也更清晰。
52-55: 私有字段重排未引入行为变化。字段类型与可空声明保持稳定,与
SetUp/TearDown生命周期配合一致。GFramework.Cqrs.Abstractions/Cqrs/INotification.cs (1)
1-1:INotification的迁移干净且一致。接口语义未变化,仅完成抽象层命名空间归位。
GFramework.Cqrs.Abstractions/Cqrs/Query/IQuery.cs (1)
1-1: 查询契约命名空间迁移正确。
IQuery/IStreamQuery的抽象边界保持稳定,迁移风险低。GFramework.Core/Cqrs/Query/QueryBase.cs (1)
14-14:QueryBase的抽象依赖切换合理。该更新保持了基类签名和泛型约束稳定,符合本次分层解耦方向。
GFramework.Core/Cqrs/Command/CommandBase.cs (1)
14-14:CommandBase命令契约引用迁移到位。该调整与查询侧迁移保持一致,降低 Core 对旧抽象命名空间的耦合。
GFramework.Core/Command/EmptyCommandInput.cs (1)
1-1:EmptyCommandInput迁移实现正确。占位输入类型职责未变,命令抽象依赖已统一到新命名空间。
Also applies to: 12-12
GFramework.Core/Command/AbstractAsyncCommandWithInput.cs (1)
1-29: LGTM!命名空间迁移正确,将 CQRS 命令抽象引用从
GFramework.Core.Abstractions.Cqrs.Command切换到GFramework.Cqrs.Abstractions.Cqrs.Command,符合 PR 整体重构方向。GFramework.Core/Cqrs/Notification/NotificationBase.cs (1)
14-15: LGTM!通知基类的 CQRS 抽象命名空间引用已正确更新,与
AbstractNotificationHandler等消费方保持一致。GFramework.Cqrs.Abstractions/Cqrs/Request/IRequestInput.cs (1)
14-20: LGTM!
IRequestInput标记接口已正确迁移到GFramework.Cqrs.Abstractions.Cqrs.Request命名空间,与RequestBase.cs等消费方的导入保持一致。GFramework.Core/Extensions/ContextAwareCqrsCommandExtensions.cs (1)
1-59: LGTM!命令扩展方法的命名空间迁移正确:
- 引用新的 CQRS 命令抽象
GFramework.Cqrs.Abstractions.Cqrs.Command- 类型移至
GFramework.Core.Extensions命名空间- 异步方法直接返回
ValueTask,避免额外的 async 状态机分配GFramework.Core/Extensions/ContextAwareCqrsQueryExtensions.cs (1)
2-4: 命名空间迁移正确。查询扩展方法已正确迁移。与
ContextAwareCqrsExtensions.cs相同,ContextAwareMediatorQueryExtensions.cs中的[Obsolete]消息也需要更新以指向新命名空间GFramework.Core.Extensions.ContextAwareCqrsQueryExtensions。GFramework.Core/Query/AbstractQueryWithResult.cs (1)
11-12: LGTM - 注意接口引用的设计意图。此类使用相对命名空间
Abstractions.Query.IQuery<TResult>实现旧版查询接口(解析为GFramework.Core.Abstractions.Query.IQuery<TResult>),同时通过IQueryInput约束引用新的 CQRS 抽象。这种设计在迁移期间为调用方提供了向后兼容性。GFramework.Core/Coroutine/Extensions/CqrsCoroutineExtensions.cs (1)
35-71: 协程异常处理逻辑清晰。
SendCommandCoroutine方法正确区分了三种完成状态:
- 取消态:统一映射为
TaskCanceledException- 故障态:解包
AggregateException暴露业务异常- 通过
ExceptionDispatchInfo保留原始栈信息GFramework.Cqrs.Tests/Coroutine/CqrsCoroutineExtensionsTests.cs (1)
17-20: 命名空间与引用迁移一致,测试语义保持稳定。这里的 using 与测试命名空间更新和本次 CQRS 抽象拆分方向一致,未引入行为层面的回归风险。
GFramework.Core/Command/AbstractCommandWithResult.cs (1)
1-2: 该段接口实现与执行路径保持一致。类型声明与显式接口执行入口在当前改动范围内是自洽的。
Also applies to: 12-13, 20-20
GFramework.Core/Command/AbstractCommandWithInput.cs (1)
1-3: 接口别名与显式实现配套清晰,兼容路径保持完整。本段改动在不改变行为的前提下完成了命名冲突规避与兼容保留。
Also applies to: 12-12, 18-18
GFramework.Cqrs.Abstractions/Cqrs/IStreamRequestHandler.cs (1)
1-1: 命名空间迁移正确,契约本身未引入行为性变更。该调整与 CQRS 抽象拆分方向一致。
GFramework.Cqrs.Abstractions/Cqrs/IRequest.cs (1)
1-1: 请求基接口的命名空间迁移一致且干净。类型身份切换方向明确,改动范围可控。
GFramework.Core.Tests/Query/QueryExecutorTests.cs (1)
2-2: 测试引用迁移正确,现有行为断言未受影响。该变更仅更新抽象来源,不改变测试意图。
Also applies to: 124-124
GFramework.Cqrs.Tests/CqrsTestRuntime.cs (1)
87-112: 同类注册副作用问题与对等测试运行时一致。这里的
RegisterHandlers也隐式调用RegisterInfrastructure,建议应用与GFramework.Core.Tests/CqrsTestRuntime.cs相同的幂等化修复策略。As per coding guidelines: Avoid hidden side effects in property getters, constructors, and registration helpers.
GFramework.Cqrs.Abstractions/Cqrs/IStreamRequest.cs (1)
1-9: 命名空间迁移与接口契约保持一致,变更清晰。该段迁移到
GFramework.Cqrs.Abstractions.Cqrs后,接口语义与文档保持稳定。GFramework.Core.Tests/Query/AsyncQueryExecutorTests.cs (1)
2-2: 测试引用切换到新 Query 抽象命名空间,方向正确。该变更与本次 CQRS 抽象拆分目标一致。
GFramework.Core/Cqrs/Request/AbstractStreamRequestHandler.cs (1)
15-15: 流式处理器基类已正确对齐新 CQRS 抽象引用。迁移后泛型约束与公开契约保持稳定。
GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs (1)
16-16: CQRS 抽象命名空间迁移一致,改动方向正确。这里与本次 CQRS 解耦目标保持一致,测试桩签名引用已对齐新抽象。
GFramework.Core.Tests/Architectures/GameContextTests.cs (1)
16-16: 测试桩 CQRS 新签名迁移完整,且与注释保持一致。这一组变更与新抽象契约对齐,方法注释也同步到位,可读性与可维护性都不错。
Also applies to: 431-473
GFramework.Core/Cqrs/Internal/CqrsDispatcher.cs (2)
38-43: 按调用传入并注入IArchitectureContext的改造是正确的。
PublishAsync、SendAsync、CreateStream全部显式接收context且先做空值校验,再在处理器/管道上注入上下文,契约落地完整。Also applies to: 77-82, 124-129, 150-151
38-43: 确认同一 dispatcher 在多次调用中注入不同上下文的行为已有测试覆盖。CqrsDispatcher 的 PublishAsync、SendAsync 和 CreateStream 方法现已接受 IArchitectureContext 参数,每次调用时通过 PrepareHandler 为 IContextAware 处理器注入当前上下文。现有测试(MediatorArchitectureIntegrationTests.cs)验证了处理器在同一上下文多次调用时接收正确的上下文,但尚未找到直接验证同一 dispatcher 实例被调用时传入不同 context 实例时的行为的测试。建议补充测试以覆盖此场景:创建多个不同的 ArchitectureContext 实例,通过同一 dispatcher 分别调用,验证处理器每次都能接收到正确的(不同的)context。
- 实现 ArchitectureContext 类,提供对系统、模型、工具等组件的访问 - 集成 CQRS runtime,支持命令、查询、事件的执行管理 - 添加服务缓存机制,优化容器解析性能 - 实现并发安全的 CQRS runtime 懒加载 - 提供同步和异步的请求处理方法 - 支持优先级排序的服务实例获取 - 添加完整的单元测试覆盖构造函数、查询、命令、事件等功能 - 配置测试项目依赖和全局引用 - 实现共享的 CQRS 测试运行时支持
- 创建 GFramework.Core.Tests 和 GFramework.Cqrs.Tests 测试项目 - 配置测试项目的全局 using 语句和依赖引用 - 添加主项目 GFramework 的元包配置文件 - 生成解决方案文件并配置所有项目引用关系 - 设置多目标框架支持 net8.0、net9.0 和 net10.0 - 配置包发布设置和仓库信息
- 新增 AutoRegisterExportedCollections 生成器文档 - 新增 AutoScene 生成器文档 - 新增 AutoUiPage 生成器文档 - 新增完整的源码生成器索引文档 - 详细介绍各生成器的使用方法和参数说明 - 提供生成代码示例和诊断信息说明 - 包含性能优势和使用示例章节
There was a problem hiding this comment.
🧹 Nitpick comments (3)
GFramework.Tests.Common/CqrsTestRuntime.cs (2)
79-99: 建议补充<exception>文档标签。根据编码规范,公共方法应包含
<exception>文档。此方法可能抛出:
ArgumentNullException:当container为 null 时TargetInvocationException:当反射调用构造函数失败时另外,Line 91 的 logger 名称使用硬编码字符串
"CqrsDispatcher",而 Line 92 使用nameof(CqrsTestRuntime),建议统一使用nameof或类型名称以保持一致性。📝 建议的文档补充
/// <summary> /// 为裸测试容器补齐默认 CQRS runtime seam。 /// </summary> /// <param name="container">目标测试容器。</param> +/// <exception cref="ArgumentNullException"><paramref name="container"/> 为 null。</exception> +/// <exception cref="TargetInvocationException">反射调用内部构造函数失败时抛出。</exception> /// <remarks> /// 这使仅使用 <see cref="MicrosoftDiContainer" /> 的测试环境也能观察与生产路径一致的 runtime 行为, /// 而无需完整启动服务模块管理器。 /// </remarks> public static void RegisterInfrastructure(MicrosoftDiContainer container) { ArgumentNullException.ThrowIfNull(container); - var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher"); + var runtimeLogger = LoggerFactoryResolver.Provider.CreateLogger(CqrsDispatcherType.Name); var registrarLogger = LoggerFactoryResolver.Provider.CreateLogger(nameof(CqrsTestRuntime));As per coding guidelines: "All public, protected, and internal types and members MUST include XML documentation comments (
///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Tests.Common/CqrsTestRuntime.cs` around lines 79 - 99, Add XML <exception> documentation to RegisterInfrastructure: document ArgumentNullException thrown when container is null and TargetInvocationException thrown when the reflection calls via CqrsDispatcherConstructor.Invoke or DefaultCqrsHandlerRegistrarConstructor.Invoke fail; update the runtime logger creation to use a consistent nameof-based identifier (e.g., nameof(CqrsDispatcher) or the concrete type) instead of the hard-coded "CqrsDispatcher" so it matches the registrar logger pattern (referencing RegisterInfrastructure, CqrsDispatcherConstructor, DefaultCqrsHandlerRegistrarConstructor, runtimeLogger, registrarLogger).
106-117:RegisterHandlers无条件调用RegisterInfrastructure可能导致重复注册。当前实现中,每次调用
RegisterHandlers都会调用RegisterInfrastructure。如果测试代码先手动调用了RegisterInfrastructure,再调用RegisterHandlers,基础设施会被注册两次。建议添加幂等性检查或在文档中明确说明调用约定。另外,Line 116 的
.Where(...).Distinct()过滤逻辑与CqrsHandlerRegistrar.RegisterHandlers内部实现重复(见 context snippet 1, lines 15-18),可以简化。♻️ 建议的改进
/// <summary> /// 通过与生产代码一致的注册入口扫描并注册指定程序集中的 CQRS 处理器。 /// </summary> /// <param name="container">承载处理器映射的测试容器。</param> /// <param name="assemblies">要扫描的程序集集合。</param> +/// <exception cref="ArgumentNullException"><paramref name="container"/> 或 <paramref name="assemblies"/> 为 null。</exception> +/// <remarks> +/// 此方法会自动调用 <see cref="RegisterInfrastructure"/>,无需单独调用。 +/// 内部注册方法会自动处理 null 元素和重复程序集的过滤。 +/// </remarks> public static void RegisterHandlers(MicrosoftDiContainer container, params Assembly[] assemblies) { ArgumentNullException.ThrowIfNull(container); ArgumentNullException.ThrowIfNull(assemblies); RegisterInfrastructure(container); var logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(CqrsTestRuntime)); RegisterHandlersMethod.Invoke( null, - [container, assemblies.Where(static assembly => assembly is not null).Distinct().ToArray(), logger]); + [container, assemblies, logger]); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Tests.Common/CqrsTestRuntime.cs` around lines 106 - 117, RegisterHandlers currently always calls RegisterInfrastructure causing double registration; make infrastructure registration idempotent by adding a private static bool flag (e.g., _infrastructureRegistered) or checking the container for an already-registered sentinel and only call RegisterInfrastructure() once, setting the flag after successful registration; also simplify the assembly argument list by removing the redundant .Where(...).Distinct() since CqrsHandlerRegistrar.RegisterHandlers already handles null and duplication—pass assemblies.ToArray() (or assemblies where you only filter nulls if you prefer) into RegisterHandlersMethod.Invoke along with the logger.GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs (1)
311-349: 建议移除固定Task.Delay,改为确定性同步以降低测试抖动。
await Task.Delay(50)对调度时序敏感,建议用“worker 就绪信号”替代时间窗口。♻️ 建议补丁
public async Task SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently() { + const int workerCount = 16; using var startGate = new ManualResetEventSlim(false); using var allowResolutionToComplete = new ManualResetEventSlim(false); + using var workersReady = new CountdownEvent(workerCount); var resolutionCallCount = 0; var runtime = new Mock<ICqrsRuntime>(MockBehavior.Strict); var container = new Mock<IIocContainer>(MockBehavior.Strict); @@ - var requests = Enumerable.Range(0, 16) + var requests = Enumerable.Range(0, workerCount) .Select(_ => Task.Run(async () => { + workersReady.Signal(); startGate.Wait(); return await context.SendRequestAsync(new TestCqrsRequest()); })) .ToArray(); + Assert.That( + workersReady.Wait(TimeSpan.FromSeconds(1)), + Is.True, + "Expected all workers to be ready before releasing start gate."); startGate.Set(); @@ - // 留出一个短暂窗口,让并发首次访问都在 runtime 尚未发布前抵达同一初始化点。 - await Task.Delay(50); allowResolutionToComplete.Set();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs` around lines 311 - 349, Replace the brittle await Task.Delay(50) timing window with deterministic synchronization: add a synchronization primitive (e.g., CountdownEvent or another ManualResetEventSlim named workersReady) that each spawned task signals once it has called startGate.Wait() and reached the point before container.Get<ICqrsRuntime>() resolution; wait on that primitive instead of Task.Delay so the test only proceeds to allowResolutionToComplete.Set() after all worker tasks have reached the initialization point, referencing the existing startGate, allowResolutionToComplete, resolutionCallCount, the ArchitectureContext instance and the tasks that call context.SendRequestAsync to coordinate readiness deterministically.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs`:
- Around line 311-349: Replace the brittle await Task.Delay(50) timing window
with deterministic synchronization: add a synchronization primitive (e.g.,
CountdownEvent or another ManualResetEventSlim named workersReady) that each
spawned task signals once it has called startGate.Wait() and reached the point
before container.Get<ICqrsRuntime>() resolution; wait on that primitive instead
of Task.Delay so the test only proceeds to allowResolutionToComplete.Set() after
all worker tasks have reached the initialization point, referencing the existing
startGate, allowResolutionToComplete, resolutionCallCount, the
ArchitectureContext instance and the tasks that call context.SendRequestAsync to
coordinate readiness deterministically.
In `@GFramework.Tests.Common/CqrsTestRuntime.cs`:
- Around line 79-99: Add XML <exception> documentation to
RegisterInfrastructure: document ArgumentNullException thrown when container is
null and TargetInvocationException thrown when the reflection calls via
CqrsDispatcherConstructor.Invoke or
DefaultCqrsHandlerRegistrarConstructor.Invoke fail; update the runtime logger
creation to use a consistent nameof-based identifier (e.g.,
nameof(CqrsDispatcher) or the concrete type) instead of the hard-coded
"CqrsDispatcher" so it matches the registrar logger pattern (referencing
RegisterInfrastructure, CqrsDispatcherConstructor,
DefaultCqrsHandlerRegistrarConstructor, runtimeLogger, registrarLogger).
- Around line 106-117: RegisterHandlers currently always calls
RegisterInfrastructure causing double registration; make infrastructure
registration idempotent by adding a private static bool flag (e.g.,
_infrastructureRegistered) or checking the container for an already-registered
sentinel and only call RegisterInfrastructure() once, setting the flag after
successful registration; also simplify the assembly argument list by removing
the redundant .Where(...).Distinct() since CqrsHandlerRegistrar.RegisterHandlers
already handles null and duplication—pass assemblies.ToArray() (or assemblies
where you only filter nulls if you prefer) into RegisterHandlersMethod.Invoke
along with the logger.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8b647f4b-c681-44cd-b14f-953d6abe0617
📒 Files selected for processing (27)
GFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/GFramework.Core.Tests.csprojGFramework.Core.Tests/GlobalUsings.csGFramework.Core/Architectures/ArchitectureContext.csGFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.csGFramework.Core/Cqrs/Internal/CqrsDispatcher.csGFramework.Core/Extensions/ContextAwareMediatorCommandExtensions.csGFramework.Core/Extensions/ContextAwareMediatorExtensions.csGFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.csGFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csprojGFramework.Cqrs.Tests/GlobalUsings.csGFramework.Godot.SourceGenerators.Tests/Behavior/AutoSceneGeneratorTests.csGFramework.Godot.SourceGenerators.Tests/Behavior/AutoUiPageGeneratorTests.csGFramework.Godot.SourceGenerators.Tests/Registration/AutoRegisterExportedCollectionsGeneratorTests.csGFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.csGFramework.Godot.SourceGenerators/Registration/AutoRegisterExportedCollectionsGenerator.csGFramework.Tests.Common/CqrsTestRuntime.csGFramework.Tests.Common/GFramework.Tests.Common.csprojGFramework.csprojGFramework.slndocs/zh-CN/source-generators/auto-register-exported-collections-generator.mddocs/zh-CN/source-generators/auto-scene-generator.mddocs/zh-CN/source-generators/auto-ui-page-generator.mddocs/zh-CN/source-generators/index.md
✅ Files skipped from review due to trivial changes (18)
- GFramework.Core.Tests/GFramework.Core.Tests.csproj
- GFramework.Core.Tests/GlobalUsings.cs
- docs/zh-CN/source-generators/auto-register-exported-collections-generator.md
- docs/zh-CN/source-generators/auto-scene-generator.md
- docs/zh-CN/source-generators/auto-ui-page-generator.md
- GFramework.Godot.SourceGenerators/Registration/AutoRegisterExportedCollectionsGenerator.cs
- docs/zh-CN/source-generators/index.md
- GFramework.csproj
- GFramework.Godot.SourceGenerators.Tests/Registration/AutoRegisterExportedCollectionsGeneratorTests.cs
- GFramework.Godot.SourceGenerators.Tests/Behavior/AutoUiPageGeneratorTests.cs
- GFramework.Godot.SourceGenerators.Tests/Behavior/AutoSceneGeneratorTests.cs
- GFramework.Core/Extensions/ContextAwareMediatorQueryExtensions.cs
- GFramework.sln
- GFramework.Cqrs.Tests/GlobalUsings.cs
- GFramework.Core/Extensions/ContextAwareMediatorCommandExtensions.cs
- GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj
- GFramework.Core/Cqrs/Internal/CqrsDispatcher.cs
- GFramework.Tests.Common/GFramework.Tests.Common.csproj
🚧 Files skipped from review as they are similar to previous changes (3)
- GFramework.Core/Extensions/ContextAwareMediatorExtensions.cs
- GFramework.Core/Coroutine/Extensions/MediatorCoroutineExtensions.cs
- GFramework.Core/Architectures/ArchitectureContext.cs
📜 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). (2)
- GitHub Check: Analyze (C#)
- GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (3)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, and edge cases
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions, and design rationale
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions, and diagnostic or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every requiredusingexplicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, constants use PascalCase; interfaces useIprefix; parameters and locals use camelCase; private fields use_camelCase
Use 4 spaces for indentation (not tabs), use Allman braces, and keepusingdirectives at the top of the file sorted consistently
Prefer one primary type per file unless the surrounding project alread...
Files:
GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Tests.Common/CqrsTestRuntime.cs
**/*.{cs,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Files:
GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Tests.Common/CqrsTestRuntime.cs
**/*SourceGenerators/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
Keep source generators deterministic and free of hidden environment or network dependencies
Files:
GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.cs
🧠 Learnings (13)
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation
Applied to files:
GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Applies to **/*.cs : ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
Applied to files:
GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.cs
📚 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.Godot.SourceGenerators/Behavior/AutoSceneGenerator.csGFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Tests.Common/CqrsTestRuntime.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Source generator changes MUST be covered by generator tests; preserve snapshot-based verification patterns already used in the repository
Applied to files:
GFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs
Applied to files:
GFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Keep tests focused on observable behavior, not implementation trivia
Applied to files:
GFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Reuse existing architecture test infrastructure when relevant: `ArchitectureTestsBase<T>`, `SyncTestArchitecture`, `AsyncTestArchitecture`
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.csGFramework.Tests.Common/CqrsTestRuntime.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Use the namespace pattern `GFramework.{Module}.{Feature}` with PascalCase segments
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : All public, protected, and internal types and members MUST include XML documentation comments (`///`) with `<summary>`, `<param>`, `<returns>`, `<exception>`, and `<remarks>` where applicable
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, and edge cases
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use IServiceModule pattern to register built-in services (EventBus, CommandExecutor, QueryExecutor) with Architecture
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Implement CQRS pattern (Command Query Responsibility Segregation) with support for both synchronous and asynchronous execution, using Mediator pattern integrated via source code generators
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs
🔇 Additional comments (10)
GFramework.Core.Tests/Cqrs/MediatorCompatibilityDeprecationTests.cs (1)
36-48: 迁移提示断言已正确同步到新命名空间。这组变更把旧兼容扩展类型的弃用提示期望值更新为新路径,且仍聚焦于可观察契约(弃用信息与编辑器可见性),方向正确。
GFramework.Godot.SourceGenerators/Behavior/AutoUiPageGenerator.cs (1)
14-16: 命名空间元数据路径修正正确。这里将
AutoUiPageAttribute的元数据名切换到.UI子命名空间,与属性定义位置一致,生成器的符号解析方向是正确的。GFramework.Godot.SourceGenerators/Behavior/AutoSceneGenerator.cs (1)
20-22:AutoSceneAttribute元数据定位更新合理。已对齐到
.UI.AutoSceneAttribute,与当前抽象层属性命名空间一致,避免生成阶段取不到属性符号。GFramework.Tests.Common/CqrsTestRuntime.cs (2)
15-21: XML 文档完整,设计意图清晰。类级别的文档说明了该测试基础设施的职责和存在理由,符合框架的文档规范。
24-42: 静态反射初始化结构合理。使用
throwOnError: true配合??抛出自定义异常的模式是合理的防御性编程。需要注意的是,如果类型或方法签名在未来重构中变更,这些静态字段初始化会在类型加载时抛出TypeInitializationException,包装内部的InvalidOperationException,这对测试诊断是有帮助的。GFramework.Core.Tests/Architectures/ArchitectureServicesTests.cs (3)
44-47: 字段顺序调整仅属整理,不影响行为。该段没有引入额外风险,可保持当前实现。
16-16: CQRS 命名空间切换方向正确。
GFramework.Cqrs.Abstractions.Cqrs的引入与当前 CQRS 抽象迁移保持一致,测试桩引用方向正确。
362-411: 公共 CQRS 方法文档与签名已对齐,修复有效。四个方法的 XML 文档已覆盖关键标签,且签名与新 CQRS 抽象一致。
As per coding guidelines: All public, protected, and internal types and members MUST include XML documentation comments (
///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable.GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs (2)
4-20: CQRS 相关 using 更新清晰且必要。
IIocContainer / ICqrsRuntime / IRequest的引入与新增并发测试场景匹配,依赖方向正确。
309-362: 并发单次解析用例覆盖了关键可观察行为。这个测试同时验证了单次解析语义与请求转发结果,覆盖点准确。
Based on learnings: Applies to **/.Tests/.cs : Keep tests focused on observable behavior, not implementation trivia
- 实现 ArchitectureContext 类的全面单元测试,覆盖构造函数、查询命令事件发送等功能 - 添加 MicrosoftDiContainer 依赖注入容器的完整测试,包括注册、获取、冻结等操作 - 创建 CqrsTestRuntime 测试基础设施,提供对 CQRS 处理器注册的受控访问 - 测试并发场景下的线程安全性,验证多线程环境下容器操作的正确性 - 实现优先级排序功能测试,确保服务按优先级正确排序和注册 - 添加各种边界条件测试,包括空参数异常处理和重复注册异常检测
- 在ArchitectureContextTests.cs中添加GFramework.Cqrs.Abstractions.Cqrs命名空间引用 - 在MicrosoftDiContainerTests.cs中添加GFramework.Cqrs.Abstractions.Cqrs命名空间引用 - 为测试文件提供必要的Cqrs相关依赖注入支持
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs`:
- Around line 306-368: The concurrent test
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently is
flaky in CI because workersReady.Wait(TimeSpan.FromSeconds(1)) can time out; fix
by increasing the wait timeout (e.g., to TimeSpan.FromSeconds(5) or 10) or by
reducing the parallelism (change const int workerCount from 16 to 8), and ensure
any related short timeouts (like the SpinWait for resolutionCallCount) are
similarly increased to avoid CI races; update the references to workerCount,
workersReady.Wait(...) and any SpinWait.SpinUntil(...) calls in this test
accordingly.
🪄 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: 3990a66c-6156-4a93-bce8-332768f3de13
📒 Files selected for processing (3)
GFramework.Core.Tests/Architectures/ArchitectureContextTests.csGFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Tests.Common/CqrsTestRuntime.cs
📜 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). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, and edge cases
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions, and design rationale
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions, and diagnostic or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every requiredusingexplicitly in C# files
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespace patternGFramework.{Module}.{Feature}with PascalCase segments
Follow standard C# naming: Types, methods, properties, events, constants use PascalCase; interfaces useIprefix; parameters and locals use camelCase; private fields use_camelCase
Use 4 spaces for indentation (not tabs), use Allman braces, and keepusingdirectives at the top of the file sorted consistently
Prefer one primary type per file unless the surrounding project alread...
Files:
GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Tests.Common/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
**/*.{cs,csproj}
📄 CodeRabbit inference engine (AGENTS.md)
Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Files:
GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Tests.Common/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Implement CQRS pattern (Command Query Responsibility Segregation) with support for both synchronous and asynchronous execution, using Mediator pattern integrated via source code generators
📚 Learning: 2026-04-05T15:30:46.211Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-05T15:30:46.211Z
Learning: Use MicrosoftDiContainer wrapping Microsoft.Extensions.DependencyInjection for unified component registration and service resolution
Applied to files:
GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Tests.Common/CqrsTestRuntime.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Keep tests focused on observable behavior, not implementation trivia
Applied to files:
GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
📚 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/Ioc/MicrosoftDiContainerTests.csGFramework.Tests.Common/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Reuse existing architecture test infrastructure when relevant: `ArchitectureTestsBase<T>`, `SyncTestArchitecture`, `AsyncTestArchitecture`
Applied to files:
GFramework.Tests.Common/CqrsTestRuntime.csGFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.Tests/*.cs : Source generator changes MUST be covered by generator tests; preserve snapshot-based verification patterns already used in the repository
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
📚 Learning: 2026-04-14T01:59:40.041Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-14T01:59:40.041Z
Learning: Applies to **/*.cs : Use the namespace pattern `GFramework.{Module}.{Feature}` with PascalCase segments
Applied to files:
GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
🪛 GitHub Check: Build and Test
GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs
[failure] 344-344: Failed Test: SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently
SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently: Expected all workers to be ready before releasing start gate.
Assert.That(workersReady.Wait(TimeSpan.FromSeconds(1)), Is.True)
Expected: True
But was: False
- at GFramework.Core.Tests.Architectures.ArchitectureContextTests.SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently() in /home/runner/work/GFramework/GFramework/GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs:line 344
at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter1.GetResult() at NUnit.Framework.Internal.AsyncToSyncAdapter.Await[TResult](TestExecutionContext context, Func1 invoke)
at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(TestExecutionContext context, Func`1 invoke)
at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.b__0()
at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
- at GFramework.Core.Tests.Architectures.ArchitectureContextTests.SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently() in /home/runner/work/GFramework/GFramework/GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs:line 344
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at GFramework.Core.Tests.Architectures.ArchitectureContextTests.SendRequestAsync_Should_ResolveCqrsRuntime_OnlyOnce_When_AccessedConcurrently()
🔇 Additional comments (7)
GFramework.Tests.Common/CqrsTestRuntime.cs (3)
23-76: 静态反射缓存实现正确。静态字段使用
throwOnError: true确保类型/方法/构造函数在类加载时即发现反射失败,并配合null-forgiving操作符和InvalidOperationException作为后备保护。这种模式对测试辅助代码是合理的。
89-107: RegisterInfrastructure 幂等注册逻辑正确。方法通过
container.Get<T>() is null检查实现幂等性,避免重复注册。与CqrsTestRuntime.RegisterInfrastructure的上下文代码片段一致。
122-133: RegisterHandlers 方法实现正确。方法正确地先调用
RegisterInfrastructure确保基础设施就绪,然后通过反射调用内部的CqrsHandlerRegistrar.RegisterHandlers静态方法。参数顺序与上下文代码片段中的签名(IIocContainer, IEnumerable<Assembly>, ILogger)匹配。GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs (3)
33-34: SetUp 正确添加 CQRS 基础设施注册。在容器初始化后调用
CqrsTestRuntime.RegisterInfrastructure确保测试环境与生产路径一致的 runtime 行为。
155-168: 幂等注册测试逻辑正确。测试验证 CQRS 基础设施在 SetUp 中已注册(各一个实例),再次调用
RegisterHandlers后仍保持各一个实例,符合幂等性预期。
349-350: Clear 后重新注册基础设施的逻辑正确。注释清晰说明了
Clear会移除手工接线的 CQRS seam,需要先恢复基础设施再验证程序集去重状态。这与RegisterInfrastructure的幂等设计一致。GFramework.Core.Tests/Architectures/ArchitectureContextTests.cs (1)
370-372: LGTM!
TestCqrsRequest作为测试专用的 CQRS 请求类型定义简洁,符合测试辅助类的设计规范。
- 将工作线程数量从16调整为8 - 添加工作线程启动超时设置为5秒 - 添加首次解析超时设置为5秒 - 使用可配置超时替代硬编码的1秒等待时间 - 提高测试稳定性和可读性
- 在ArchitectureContextTests中添加GFramework.Cqrs.Abstractions.Cqrs命名空间引用
- 移除 ICommand<TResponse> 和 ICommand 的空实现体 - 移除 IQuery<TResponse> 和 IStreamQuery<TResponse> 的空实现体 - 移除 INotification、IRequest<TResponse>、IStreamRequest<TResponse> 的空实现体 - 将 IStreamCommand<TResponse> 分离到独立文件中 - 将 IStreamQuery<TResponse> 分离到独立文件中 - 保持所有接口的核心功能不变,仅简化语法结构
f7b4ae9
into
refactor/cqrs-architecture-decoupling
Summary by CodeRabbit
发布说明
新功能
重构
测试
文档