Feat/Enhance CQRS benchmarks coverage and generated invoker descriptor validation#348
Conversation
- 更新 CQRS 栏目中的 generated invoker、fallback 分层与 notification publisher 选择边界说明 - 对齐生成器专题页与当前 runtime 注册和分发实现的实际行为
- 新增 notification publisher 多实例冲突时抛错的回归测试 - 补充首次解析后复用同一 publisher 且不重复查容器的缓存测试 - 更新测试发布器计数以验证缓存命中的发布调用次数
- 新增 RequestStartupBenchmarks 的 Mediator 初始化与冷启动 benchmark 路径 - 更新 request 与 handler 契约以复用单文件内的 Mediator concrete host 对照
- 修复 generated request/stream invoker descriptor 枚举阶段对异常、重复 pair 与不一致元数据的防守行为 - 补充 generated invoker provider descriptor 边界回归测试,锁定回退与首条生效语义
- 更新 archive todo 顶部导航,补充截止恢复点、阶段索引与跳转约定 - 更新 archive trace 顶部索引,突出验证锚点与阶段回看入口
- 更新当前 HEAD 已覆盖的 request、stream、notification benchmark 矩阵 - 补充 --artifacts-suffix 的并发运行隔离约束与使用边界 - 明确 short-job smoke 的结论边界,并将未覆盖维度改写为当前缺口
- 新增 StreamStartupBenchmarks,补齐 stream 的 initialization 与 cold-start first-hit 对照 - 内嵌 generated registry 与最小宿主搭建,保持 benchmark 场景在单文件内自管理
- 新增 NotificationStartupBenchmarks,补齐 notification 的 Initialization 与 ColdStart 对称矩阵 - 复用最小宿主搭建路径,对齐 GFramework.CQRS、Mediator 与 MediatR 的单处理器首击发布对照 - 修复 cold-start 方法的资源释放时序,确保 benchmark 构建零警告通过
- 新增 NotificationLifetime 基准并补充验证结果 - 更新 CQRS README 与 legacy Command/Query 迁移说明 - 补充 registration fallback 回归测试并同步 ai-plan 恢复点
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📜 Recent review details⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🧰 Additional context used📓 Path-based instructions (6)**/Cqrs/**/*.cs📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.cs📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.Tests/**/*.cs📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/public/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
ai-plan/public/**/traces/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (2)📚 Learning: 2026-04-06T12:45:43.921ZApplied to files:
📚 Learning: 2026-05-11T06:15:15.057ZApplied to files:
🪛 LanguageToolai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md[grammar] ~10-~10: Ensure spelling is correct (QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1) 🔇 Additional comments (6)
📝 WalkthroughWalkthrough本 PR 增加多个 BenchmarkDotNet 套件(通知生命周期/启动、请求/流 启动)、扩展单元测试覆盖以验证 dispatcher 缓存与生成描述符边界、在 CqrsHandlerRegistrar 中加入生成描述符的防御与验证逻辑,并同步更新 CQRS 文档与迁移追踪记录。 Changes基准测试基础设施与实现
单元测试与验证覆盖
运行时实现与文档
迁移追踪与治理
🎯 4 (Complex) | ⏱️ ~45 minutes可能相关的 PR
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Test ResultsDetails
Insights
Fail Rate
build-and-test: Run #1107
🎉 All tests passed!Slowest Tests
± Comparison with run #1106 at 1d63a95 | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 49 runs. Github Test Reporter by CTRF 💚 |
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| dotnet-format | yes | 1 | no | 5.21s | ||
| ✅ REPOSITORY | gitleaks | yes | no | no | 8.12s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 5.94s |
Detailed Issues
⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114
----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https
----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.Exception: Restore operation failed.
at Microsoft.CodeAnalysis.Tools.CodeFormatter.OpenMSBuildWorkspaceAsync(String solutionOrProjectPath, WorkspaceType workspaceType, Boolean noRestore, Boolean requiresSemantics, String binaryLogPath, Boolean logWorkspaceWarnings, ILogger logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.CodeFormatter.FormatWorkspaceAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken, String binaryLogPath)
at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.FormatAsync(FormatOptions formatOptions, ILogger`1 logger, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

Show us your support by starring ⭐ the repository
|
| Filename | Overview |
|---|---|
| GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs | Adds exception-safe descriptor enumeration, null-entry guards, and per-call duplicate detection for both request and stream invoker descriptors. The catch blocks in the two new validation helpers access descriptor type fields that could be null, which could cause the catch block itself to throw in malformed-provider scenarios. |
| GFramework.Cqrs.Benchmarks/Messaging/NotificationLifetimeBenchmarks.cs | New benchmark comparing Singleton/Scoped/Transient handler lifetimes; _scopedContainer is now correctly passed to BenchmarkCleanupHelper.DisposeAll in Cleanup(), addressing the previously flagged disposal gap. |
| GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs | Adds comprehensive edge-case tests for generated invoker descriptor enumeration: empty, throwing, null-returning, duplicate, mismatched, and invalid-first/valid-second scenarios for both request and stream paths. |
| GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.cs | New tests for notification publisher selection and ambiguity detection, including multiple-publisher rejection and publisher caching after first publish. |
| GFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.cs | New cold-start stream benchmark comparing reflection vs. source-generated invoker path and MediatR; uses IterationSetup to clear the dispatcher static cache outside measurement to isolate first-binding cost only. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[RegisterGeneratedRequestInvokerDescriptors] --> B{provider implements IEnumeratesCqrsRequestInvokerDescriptors?}
B -- No --> Z[Return]
B -- Yes --> C[Call GetDescriptors]
C --> D{Throws?}
D -- Yes --> E[Log Warn, Return]
D -- No --> F{Returns null?}
F -- Yes --> G[Log Warn, Return]
F -- No --> H[For each descriptorEntry]
H --> I{entry is null?}
I -- Yes --> J[Log Warn, continue]
I -- No --> K[Create InvokerDescriptorKey]
K --> L[TryValidateEnumeratedRequestInvokerDescriptor]
L --> M{TryGetDescriptor returns match?}
M -- No/throws --> N[Log Warn, return false]
M -- Yes --> O{InvokerMethod and HandlerType match?}
O -- No --> P[Log Warn, return false]
O -- Yes --> Q[return true]
N --> R{valid?}
P --> R
Q --> R
R -- false --> S[continue loop]
R -- true --> T{registeredKeys.Add successful?}
T -- No duplicate --> U[RegisterGeneratedRequestInvokerDescriptor to dispatcher global cache]
T -- Duplicate --> V[Log Warn, continue]
U --> H
S --> H
V --> H
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs:516-521
**Catch block can itself throw if descriptor entry has null types**
The catch block interpolates `descriptorEntry.RequestType.FullName` and `descriptorEntry.ResponseType.FullName` directly. If a malformed provider returned a `CqrsRequestInvokerDescriptorEntry` whose `RequestType` or `ResponseType` is null, `TryGetDescriptor` would throw (e.g., `ArgumentNullException`), the catch would be entered, and then the log message interpolation itself would throw a `NullReferenceException` that escapes the catch block uncaught — defeating the entire safety net. The same pattern is repeated in the catch block of `TryValidateEnumeratedStreamInvokerDescriptor` (line 561–566). Using null-conditional access like `descriptorEntry.RequestType?.FullName ?? "<null>"` in both catch blocks would make them unconditionally safe.
Reviews (2): Last reviewed commit: "fix(cqrs): 收口 PR review 剩余问题" | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 15-17: Update the inconsistent PR anchor references: find every
occurrence of the string "PR `#347`" in this document (notably the active PR 锚点 at
the recovery entry showing `CQRS-REWRITE-RP-133` / `Phase 8` and the active
trace section around line 49) and change them to "PR `#348`" so the recovery point
and active trace match the current PR; verify there are no remaining "PR `#347`"
instances elsewhere in the file to ensure all tracking anchors are synchronized.
In `@GFramework.Cqrs.Benchmarks/Messaging/NotificationLifetimeBenchmarks.cs`:
- Around line 144-183: The three public benchmark methods
PublishNotification_Baseline, PublishNotification_GFrameworkCqrs, and
PublishNotification_MediatR (and the public Handle(...) mentioned) only have
<summary> XML docs — add missing <param> and <returns> XML tags to each method:
document the method parameters (e.g., the notification parameter and
CancellationToken when applicable or the implicit BenchmarkContext usage) with
<param name="..."> and describe the return type with <returns> (ValueTask or
Task), and include any relevant <remarks> or <exception> if applicable; also
apply the same <param>/<returns> additions to the other public methods noted
around lines 296–301 so all public/protected/internal members follow the XML
documentation contract.
- Around line 52-68: The HandlerLifetime enum lacks the repository-standard
[GenerateEnumExtensions] attribute; add [GenerateEnumExtensions] immediately
above the public enum HandlerLifetime declaration so the generated enum
extension methods are produced for Singleton/Scoped/Transient and keep enum
usage consistent with other enums.
In `@GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs`:
- Around line 360-371: The code currently adds the InvokerDescriptorKey to
registeredKeys before validation, which can drop a later valid descriptor if the
first with the same key fails validation; change the flow so that you first call
TryValidateEnumeratedRequestInvokerDescriptor(provider, descriptorEntry,
assemblyName, logger) and only if it returns true attempt to add the new
InvokerDescriptorKey(descriptorEntry.RequestType, descriptorEntry.ResponseType)
to registeredKeys, logging and continuing on duplicates; apply the same change
to the analogous stream-path validation (the other block that follows the
TryValidate... stream validator) so de-duplication happens after successful
validation.
- Around line 504-506: The comparison using ReferenceEquals on MethodInfo is
incorrect; replace ReferenceEquals(resolvedDescriptor.InvokerMethod,
descriptorEntry.Descriptor.InvokerMethod) with an equality check (use == or
.Equals) so MethodInfo instances that are equivalent across reflection calls are
treated as equal; update both occurrences around the conditional that involves
resolvedDescriptor.InvokerMethod and descriptorEntry.Descriptor.InvokerMethod in
CqrsHandlerRegistrar (also mirror the same change at the other comparison near
lines 549-551) so TryGetDescriptor returned descriptors are not erroneously
rejected.
🪄 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: 95b0e463-1e09-408e-8754-892a16814bb4
📒 Files selected for processing (19)
GFramework.Cqrs.Benchmarks/Messaging/NotificationLifetimeBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.csGFramework.Cqrs.Benchmarks/README.mdGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.csGFramework.Cqrs/Internal/CqrsHandlerRegistrar.csGFramework.Cqrs/README.mdai-plan/public/cqrs-rewrite/archive/todos/cqrs-rewrite-migration-tracking-history-through-rp131.mdai-plan/public/cqrs-rewrite/archive/traces/cqrs-rewrite-migration-trace-history-through-rp131.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mddocs/zh-CN/core/command.mddocs/zh-CN/core/cqrs.mddocs/zh-CN/core/query.mddocs/zh-CN/source-generators/cqrs-handler-registry-generator.md
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Analyze (C#)
- GitHub Check: Code Quality & Security
- GitHub Check: Build and Test
🧰 Additional context used
📓 Path-based instructions (13)
ai-plan/public/**
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/public/**: Contributors MUST keep committedai-plan/public/**content safe to publish in Git history
Active tracking and trace files are recovery entrypoints, not append-only changelogs. They MUST stay concise enough forbootto locate the current recovery point quickly
When completed and validated stages begin to accumulate, contributors MUST archive their detailed history out of the activetodos/andtraces/entry files in the same change. Keep only the current recovery point, active facts, active risks, immediate next step, and pointers to the relevant archive files in the default boot path
When a topic is fully complete, move the entire topic directory underai-plan/public/archive/<topic>/and remove it fromai-plan/public/README.mdin the same change
When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery document and the trace at each meaningful milestone before pausing or handing work off
If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in the active recovery document or trace before continuing implementation
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/archive/traces/cqrs-rewrite-migration-trace-history-through-rp131.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/archive/todos/cqrs-rewrite-migration-tracking-history-through-rp131.md
ai-plan/**
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/**: Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP addresses, proprietary URLs, or other sensitive environment details into anyai-plan/**file
Never record absolute file-system paths inai-plan/**; use repository-relative paths, branch names, PR numbers, or stable document identifiers instead
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/archive/traces/cqrs-rewrite-migration-trace-history-through-rp131.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/archive/todos/cqrs-rewrite-migration-tracking-history-through-rp131.md
ai-plan/public/**/traces/**
📄 CodeRabbit inference engine (AGENTS.md)
Contributors MUST maintain a matching execution trace under
ai-plan/public/<topic>/traces/for complex work. The trace should record the current date, key decisions, validation milestones, and the immediate next step
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/archive/traces/cqrs-rewrite-migration-trace-history-through-rp131.md
docs/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Documentation should be organized with Chinese content in docs/zh-CN/ and structured to include getting started, module-specific capabilities (Core, Game, Godot, ECS), source generator usage, tutorials, best practices, and troubleshooting
Files:
docs/zh-CN/core/query.mddocs/zh-CN/core/command.mddocs/zh-CN/source-generators/cqrs-handler-registry-generator.mddocs/zh-CN/core/cqrs.md
{README.md,docs/**}
📄 CodeRabbit inference engine (AGENTS.md)
{README.md,docs/**}: Update the relevantREADME.mdordocs/page when behavior, setup steps, architecture guidance, or user-facing examples change
Public documentation underREADME.mdanddocs/MUST stay reader-facing. Do not publish governance-only content such as inventory tables, coverage baselines, review queues, batch metrics, recovery points, trace summaries, or "this still needs a later audit wave" notes
Public documentation MUST use semantic section titles and link labels. Do not surface raw filenames or paths such asREADME.md、game/index.md、../core/cqrs.mdas reader-facing navigation text when a meaningful destination label is available
Public documentation MUST avoid rhetorical, self-referential, or AI-sounding headings and prompts. Prefer neutral labels instead of phrases like "你真正会用到的公开入口"、"先理解包关系"、"这个栏目应该回答什么" or "想看……转到……"
Public documentation MUST present limitations, suitability, and migration boundaries as adoption guidance for readers. Do not publish internal-governance or product-roadmap wording inREADME.mdordocs/**; that material belongs inai-plan/**
Files:
docs/zh-CN/core/query.mddocs/zh-CN/core/command.mddocs/zh-CN/source-generators/cqrs-handler-registry-generator.mddocs/zh-CN/core/cqrs.md
docs/**
📄 CodeRabbit inference engine (AGENTS.md)
docs/**: The main documentation site lives underdocs/, with Chinese content underdocs/zh-CN/
Keep code samples, package names, and command examples aligned with the current repository state
Prefer documenting behavior and design intent, not only API surface
When a public page references XML docs or API coverage, convert that evidence into reader-facing guidance: explain which types, namespaces, or entry points readers should inspect and why, instead of exposing audit counts or governance terminology
If an existing documentation page no longer reflects the current implementation, fixing the code without fixing the documentation is considered incomplete work
Do not rely on "the code is self-explanatory" for framework features that consumers need to adopt; write the adoption path down so future users do not need to rediscover it from source
When examples are rewritten, preserve only the parts that remain true. Delete or replace speculative examples instead of lightly editing them into another inaccurate form
Files:
docs/zh-CN/core/query.mddocs/zh-CN/core/command.mddocs/zh-CN/source-generators/cqrs-handler-registry-generator.mddocs/zh-CN/core/cqrs.md
docs/zh-CN/**
📄 CodeRabbit inference engine (AGENTS.md)
docs/zh-CN/**: When a feature is added, removed, renamed, or substantially refactored, contributors MUST update or create the corresponding user-facing integration documentation indocs/zh-CN/in the same change
For integration-oriented features such as the AI-First config system, documentation MUST cover: project directory layout and file conventions, required project or package wiring, minimal working usage example, and migration or compatibility notes when behavior changes
Files:
docs/zh-CN/core/query.mddocs/zh-CN/core/command.mddocs/zh-CN/source-generators/cqrs-handler-registry-generator.mddocs/zh-CN/core/cqrs.md
**/Cqrs/**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
Use CQRS (Command Query Responsibility Segregation) pattern with the Cqrs naming entry point instead of the historical Mediator alias
Files:
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///)
XML documentation comments MUST use<summary>,<param>,<returns>,<exception>, and<remarks>where applicable, explaining intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly in XML documentation
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds and compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Avoid obvious comments such as// increment i
Methods with non-trivial logic MUST document: The core idea, Key decisions, and Edge case handling, if any
Comments MUST NOT be trivial, redundant, or misleading. Prefer explainingwhyandwhen, not justwhat. Code should remain understandable without requiring external context. Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports. Declare every requiredusingexplicitly
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, and constants use PascalCase; Interfaces useIprefix; Parameters and locals use camelCase; Private fields use_camelCase
Use 4 spaces for indentation. Do not use tabs
Use Allman braces
Keepusingdirectives at the top...
Files:
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Benchmarks/Messaging/NotificationStartupBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationLifetimeBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs/Internal/CqrsHandlerRegistrar.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs
**/*.Tests/**/*.cs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.Tests/**/*.cs: Mirror the source structure in test projects whenever practical
Reuse existing architecture test infrastructure when relevant:ArchitectureTestsBase<T>,SyncTestArchitecture,AsyncTestArchitecture
Files:
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs
ai-plan/public/**/todos/**
📄 CodeRabbit inference engine (AGENTS.md)
ai-plan/public/**/todos/**: When working from a tracked implementation plan, contributors MUST update the corresponding tracking document underai-plan/public/<topic>/todos/in the same change
Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended recovery point
For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery document underai-plan/public/<topic>/todos/before making substantive code changes
Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next recommended resume step so another contributor or subagent can continue the work safely
Files:
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/archive/todos/cqrs-rewrite-migration-tracking-history-through-rp131.md
**/*{Startup,Init,Register,Setup,Configure}*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
CQRS handler registration should use generated products from CqrsHandlerRegistryGenerator at runtime, falling back to reflection scanning when generation cannot cover cases; explicitly register handlers from non-default assemblies using RegisterCqrsHandlersFromAssembly(...) or RegisterCqrsHandlersFromAssemblies(...)
Files:
GFramework.Cqrs.Benchmarks/Messaging/NotificationStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs
**/README.md
📄 CodeRabbit inference engine (AGENTS.md)
**/README.md: Use the canonical filenameREADME.md. Do not introduce newReadMe.mdor other filename variants
A module README MUST describe: the module's purpose, the relationship to adjacent runtime, abstractions, or generator packages, the major subdirectories or subsystems the reader is expected to use, the minimum adoption path, and the correspondingdocs/zh-CN/entry points
If a module's responsibilities, setup, public API surface, generator inputs, or adoption path change, update that module'sREADME.mdin the same change
Files:
GFramework.Cqrs.Benchmarks/README.mdGFramework.Cqrs/README.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.csGFramework.Cqrs.Benchmarks/Messaging/NotificationStartupBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationLifetimeBenchmarks.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs/Internal/CqrsHandlerRegistrar.csGFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs
🪛 LanguageTool
docs/zh-CN/source-generators/cqrs-handler-registry-generator.md
[uncategorized] ~93-~93: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...数据为空、只保留 marker 语义,或 registry 整体不可用时,才退回整程序集补扫 8. 同一程序集按稳定键去重,避免重复注册 这个行为由 [运行时注册流...
(wa5)
[uncategorized] ~132-~132: 您的意思是“"不"齐”?
Context: ...,才允许发射依赖 fallback 的结果 fallback 在这里表示“补齐生成注册器没有直接接线的剩余 handler”,不是“生成器一出现就重新扫描整...
(BU)
GFramework.Cqrs/README.md
[uncategorized] ~121-~121: 您的意思是“"不"齐”?
Context: ...time 并接线默认注册流程;只有在裸容器、测试宿主或自定义组合根里,才需要显式补齐 runtime、publisher 策略或额外程序集注册。 ## 运行时行...
(BU)
[uncategorized] ~141-~141: 动词的修饰一般为‘形容词(副词)+地+动词’。您的意思是否是:快"地"分发
Context: ...察失败”的场景,而不是把 publish 切成另一条 generated 或更快的分发通道。 如果你需要显式保留默认顺序语义,也可以在组合根里直接声明: ``...
(wb4)
[uncategorized] ~200-~200: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ...。 - CqrsReflectionFallbackAttribute 可以多次声明,并同时承载 Type[] 与 string[] 两类 fallback...
(wa5)
[uncategorized] ~201-~201: 数词与名词之间一般应存在量词,可能缺少量词。
Context: ... marker、空 fallback 元数据,或生成注册器整体不可用时,才会退回整程序集扫描。 - 处理器以 transient 方式注册,避免上下文感知处理器在并发...
(wa5)
[uncategorized] ~204-~204: 您的意思是“"不"齐”?
Context: ...ore` 架构初始化路径,这些步骤通常由框架自动完成;裸容器或测试环境则需要显式补齐 runtime 与注册入口。 ## 适用边界 - 这个包是默认实现,不是...
(BU)
ai-plan/public/cqrs-rewrite/archive/todos/cqrs-rewrite-migration-tracking-history-through-rp131.md
[uncategorized] ~11-~11: 您的意思是“"不"读”?
Context: ... active todos/ 与 traces/,再从 archive 补读所需历史。 - 若只需要历史结论,优先查本文件的阶段索引;若需要当轮验证细节、...
(BU)
🔇 Additional comments (14)
docs/zh-CN/core/command.md (1)
112-151: 兼容入口与迁移边界写得很清楚。这段把 bridge、fallback 条件和“继续保留/开始迁移”的判断标准都落到了可执行层面,便于读者直接决策。
GFramework.Cqrs.Tests/Cqrs/CqrsNotificationPublisherTests.cs (2)
94-156: 新增通知发布器歧义与缓存测试覆盖到位。多发布器冲突和首次解析后复用这两条关键路径都被明确断言,回归保护价值很高。
329-347:PublishCallCount的引入很实用。计数属性与递增逻辑让缓存复用断言更直接,也避免了仅靠布尔状态带来的歧义。
GFramework.Cqrs.Tests/Cqrs/CqrsRegistrationServiceTests.cs (2)
90-176: 程序集键回退路径测试补得很扎实。
FullName与Name缺失链路都覆盖到了,并且校验了跨调用去重行为。
184-208:CreateAssembly的可配置退化模型设计合理。这个重载把测试意图从“构造 mock 细节”里解耦出来,后续扩展类似场景会更轻松。
GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs (1)
20-260: 第三组Mediator基线接入完整。初始化与冷启动两组都补齐了,并且服务提供器生命周期也同步纳入清理逻辑,基准可比性更强。
GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs (2)
312-872: 共享 binding 下“零行为→有行为”切换场景覆盖非常关键。这些新增用例把 executor 延迟创建与上下文重新注入的边界都钉住了,能有效防止缓存路径回归。
873-1008:DispatcherCacheFixtureOptions的引入很加分。通过可选注册开关来组合测试形状,明显提升了夹具表达力和后续可维护性。
GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs (2)
451-569: 生成描述符异常/重复/不一致三类回退用例补得很全面。这组测试把 provider 预热边界行为覆盖得很完整,能很好约束 runtime fallback 的稳定性。
983-1357: 这些测试用 registry 替身设计清晰且贴合场景。每种异常形态都有独立实现,断言来源明确,后续定位失败原因会很直接。
docs/zh-CN/source-generators/cqrs-handler-registry-generator.md (1)
43-148: generated invoker 覆盖边界与 fallback 语义说明很到位。“只覆盖 request/stream、notification 仍走 publisher 策略”以及回退触发条件都讲清楚了,和采用决策直接相关。
docs/zh-CN/core/query.md (1)
88-127: 旧查询兼容入口与 CQRS bridge 的关系描述清晰。回退条件、适用场景和迁移判断都给到了可操作标准,能降低存量项目迁移歧义。
GFramework.Cqrs.Benchmarks/Messaging/NotificationStartupBenchmarks.cs (1)
63-98: 基准分组与生命周期管理实现清晰
Initialization/ColdStart分组边界明确,迭代缓存重置与全局资源释放完整,便于稳定对比三条宿主路径。Also applies to: 132-169
GFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.cs (1)
138-181: 三路径冷启动对照实现完整且边界一致每条 cold-start 路径都采用“新宿主 + 首元素命中”的一致测量方式,配合 generated registry 描述符实现,结果可比性很好。
Also applies to: 337-429
- 修复 NotificationLifetimeBenchmarks 的 scoped 容器释放与公开 XML 契约缺口 - 修复 generated descriptor 预热阶段先去重后校验导致的有效后继条目丢失问题 - 更新 generated descriptor 的 MethodInfo 比较方式并补充 request/stream 回归测试 - 同步 cqrs-rewrite active tracking 与 trace 的当前 PR 锚点到 PR #348
Summary
Test ResultsDetails
Insights
Fail Rate
build-and-test: Run #1108
🎉 All tests passed!Slowest Tests
± Comparison with run #1107 at c9d5ef8 | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 50 runs. Github Test Reporter by CTRF 💚 |
Summary by CodeRabbit
版本更新说明
性能评测
可靠性改进
测试
文档澄清