Test/Add comprehensive CQRS benchmarking suite with reflection and generated invoker paths#326
Conversation
- 新增独立的 GFramework.Cqrs.Benchmarks 项目并引入 request、notification 对比场景 - 补充 request 与 stream invoker provider 的 mixed direct/reflected 顺序回归测试 - 更新 solution、meta-package 排除规则与 CQRS ai-plan 恢复点
- 新增 StreamingBenchmarks 并对齐 baseline、GFramework.Cqrs 与 MediatR 的完整枚举对照 - 更新 benchmark README 与 CQRS ai-plan 恢复点,记录 stream 场景落地
- 新增 request pipeline 0/1/4 数量矩阵基准并保持 GFramework.Cqrs 与 MediatR 对照 - 更新 benchmark README 说明当前场景覆盖与后续扩展方向 - 补充 cqrs-rewrite 跟踪与 trace 的 RP-086 恢复点和验证记录
- 新增 request initialization 与 cold-start 基准并对齐当前 runtime 启动口径 - 通过清理 dispatcher 静态缓存隔离 GFramework.Cqrs 首次分发测量结果 - 更新 benchmark README 与 cqrs-rewrite RP-087 跟踪记录
- 新增 request reflection 与 generated invoker provider 的 steady-state 对照基准 - 引入 handwritten generated registry/provider 以走通真实 registrar 与 dispatcher 预热链路 - 更新 benchmark README 与 cqrs-rewrite RP-088 跟踪记录
- 新增 stream generated invoker benchmark 与手写 registry,对照 reflection runtime、generated runtime 和 MediatR 的完整枚举开销 - 更新 benchmark README,补充 generated stream invoker provider 的场景说明与后续扩展方向 - 更新 cqrs-rewrite 跟踪与 trace,记录 RP-089 的基线、验证结果和下一批建议
|
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 (6)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (8)**/*[!.]*📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{md,mdx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.cs📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{cs,ts,tsx,js,jsx,py,sh}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{cs,ts,tsx,js,jsx,py}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{csproj,cs}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2026-04-06T12:45:43.921ZApplied to files:
🪛 LanguageToolai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md[grammar] ~498-~498: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) [uncategorized] ~539-~539: The official name of this software platform is spelled with a capital “H”. (GITHUB) [grammar] ~539-~539: Ensure spelling is correct (QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1) 🔇 Additional comments (8)
📝 WalkthroughWalkthrough新增独立的 GFramework.Cqrs.Benchmarks 项目,包含 BenchmarkDotNet 基准套件、基准运行入口、DI/宿主与 MediatR 构建辅助、生成/反射调用器注册表、缓存清理工具、多个请求/通知/流/管道/启动基准实现、相关源生成器稳定性测试与 CI 基准工作流。 Changes基准测试与性能对标基础设施
Sequence Diagram(s)sequenceDiagram
participant Bench as "Benchmark Runner"
participant Host as "BenchmarkHostFactory / DI"
participant CQRS as "GFramework.Cqrs.Runtime"
participant Med as "MediatR"
participant Handler as "Handler"
Bench->>Host: GlobalSetup() / 创建容器与服务提供者
Host->>CQRS: 注册处理器、生成/反射注册表
Host->>Med: 注册 MediatR 处理器
Bench->>CQRS: 调用 Send/Publish/Stream
CQRS->>Handler: 调用 已注册 Handler (反射或生成)
Handler-->>CQRS: 返回结果 / 枚举
Bench->>Med: 调用 MediatR Send/Publish/Stream
Med->>Handler: 调用 MediatR Handler
Handler-->>Med: 返回结果 / 枚举
Bench->>Bench: 收集并记录基准结果(含自定义列)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 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
build-and-test: Run #1060
🎉 All tests passed!Slowest Tests
± Comparison with run #1055 at 043530f | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 24 runs. Github Test Reporter by CTRF 💚 |
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| dotnet-format | yes | 1 | no | 5.77s | ||
| ✅ REPOSITORY | gitleaks | yes | no | no | 8.63s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 6.22s |
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 |
|---|---|
| .github/workflows/benchmark.yml | New CI workflow for building/running benchmarks on demand; shell injection previously flagged is now correctly mitigated by routing the input through an env variable before the shell consumes it. |
| GFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs | Centralised reflection-based cache-clearing helper extracted from three previously duplicated copies; works correctly but is tightly coupled to GFramework internal type names and field names. |
| GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs | Previously flagged issues resolved: dual-baseline category grouping added via AddLogicalGroupRules, cache clearing moved to [IterationSetup], and handler lifetimes are now symmetric (both Transient). |
| GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs | Clean steady-state benchmark comparing direct handler call, reflection dispatch, generated invoker dispatch, and MediatR; handler lifetimes are symmetric (Transient) across frameworks. |
| GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs | Mirrors RequestInvokerBenchmarks for streaming paths; shared EnumerateAsync helper keeps enumeration bodies identical across all three handler types, isolating dispatch overhead cleanly. |
| GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs | Pipeline benchmark with [Params(0,1,4)]; handler and pipeline behavior lifetimes are Singleton for both frameworks, making memory diagnoser numbers comparable. |
| GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs | Steady-state notification publish benchmark; both handlers registered as Singleton instances, so allocation numbers are comparable between frameworks. |
| GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.cs | Well-structured factory centralising GFramework container and MediatR service-provider creation; TypeEvaluator filter prevents other benchmark handlers from polluting each class's MediatR registration. |
| GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs | New test validating that the generated registry descriptor ordering is deterministic under mixed implementations; no issues found. |
| GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj | New standalone benchmark project correctly excluded from the main build; references BenchmarkDotNet 0.15.8 and MediatR 13.1.0 as comparison targets. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[BenchmarkDotNet Runner] --> B{Benchmark Class}
B --> C[RequestStartupBenchmarks]
B --> D[RequestInvokerBenchmarks]
B --> E[StreamInvokerBenchmarks]
B --> F[RequestPipelineBenchmarks]
B --> G[NotificationBenchmarks]
C --> CS1["[IterationSetup] ClearDispatcherCaches()"]
CS1 --> CS2["Initialization_MediatR / GFrameworkCqrs"]
CS1 --> CS3["ColdStart_MediatR / GFrameworkCqrs"]
D --> DG["[GlobalSetup] ClearCaches + Build 3 runtimes"]
DG --> DB1["SendRequest_Baseline (direct)"]
DG --> DB2["SendRequest_GFrameworkReflection"]
DG --> DB3["SendRequest_GFrameworkGenerated"]
DG --> DB4["SendRequest_MediatR"]
E --> EG["[GlobalSetup] ClearCaches + Build 3 stream runtimes"]
EG --> EB1["Stream_Baseline / Reflection / Generated / MediatR"]
F --> FP["[Params: 0,1,4] [GlobalSetup] ClearCaches"]
FP --> FB1["SendRequest_Baseline / GFrameworkCqrs / MediatR"]
G --> GS["[GlobalSetup] steady-state, no cache clearing"]
GS --> GB1["PublishNotification_GFrameworkCqrs / MediatR"]
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.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.cs:35-48
**Brittle coupling to internal type and field names**
`ClearDispatcherCache` resolves `GFramework.Cqrs.Internal.CqrsDispatcher` and its five private static fields entirely by string. If any of those names is changed during a refactor (rename, access-modifier change, field consolidation), every benchmark that calls `ClearDispatcherCaches()` will fail at runtime — either with a `TypeLoadException` from `throwOnError: true`, or with the `InvalidOperationException` thrown for a missing field — rather than with a compile-time or source-generator error. Since this helper is the single gate-keeper for all cold-start and invoker benchmarks, a silent rename in the production library would cause every benchmark run to abort before a single measurement is taken. Consider exposing a thin `internal` test-seam on `CqrsDispatcher` so the coupling is validated at compile time.
Reviews (4): Last reviewed commit: "fix(cqrs): 收敛 benchmark review 收尾问题" | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (1)
57-81: 💤 Low value「最近权威验证」节中同一构建命令重复记录 6 次,建议合并。
dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release连同备注共出现 6 次(第 57–73 行),license-header.py与git diff --check各重复 2 次(第 74–81 行)。作为 AI 规划文档,累积追加导致的冗余可以接受,但建议在下一次归档周期时合并为最终一次结果,保持文档可读性。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md` around lines 57 - 81, The "最近权威验证" section contains repeated entries of the same build/check commands (notably the command string `dotnet build GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release` repeated six times and `python3 scripts/license-header.py --check` / `git diff --check` repeated twice); collapse those duplicates by keeping a single consolidated entry per unique command (e.g., one `dotnet build ... -c Release` with a combined remark listing added benchmark/regression checkpoints such as `StreamingBenchmarks`, `RequestPipelineBenchmarks`, `RequestStartupBenchmarks`, `RequestInvokerBenchmarks`, and `StreamInvokerBenchmarks`) and similarly merge the duplicate `license-header.py --check` and `git diff --check` lines into single entries to improve readability while preserving all noted results.
🤖 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/traces/cqrs-rewrite-migration-trace.md`:
- Around line 453-466: The list item starting with "2. 若要继续贴近 `Mediator` 的
comparison benchmark 设计哲学…" is misplaced under the "### 验证(RP-089)" section;
move that paragraph back into the ordered list under "### 当前下一步(RP-089)" so that
the section order remains "当前下一步(RP-089)" followed by "### 验证(RP-089)", adjust
the numbering in the "当前下一步(RP-089)" list if needed, and ensure the stray item
text matches exact wording used elsewhere to avoid duplication.
In `@GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj`:
- Around line 17-19: The project is using MediatR 13.x which emits
license-warning logs (LuckyPennySoftware.MediatR.License) that will pollute
benchmark output; update the DI/logging setup or package versions: either set
the MediatR license key during service registration (configure the License Key
in your DI registration where MediatR is added), or add a logging filter to
exclude the LuckyPennySoftware.MediatR.License category in the benchmark host
logging configuration, and also bump BenchmarkDotNet from 0.15.6 to 0.15.8 in
GFramework.Cqrs.Benchmarks.csproj to pick up the latest fixes; reference the
PackageReference entries for MediatR and BenchmarkDotNet when making these
changes.
In `@GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs`:
- Around line 53-89: The two benchmarks measure different phases:
Initialization_MediatR resolves IMediator from the prebuilt container created in
Setup(), while Initialization_GFrameworkCqrs calls CreateGFrameworkRuntime()
creating a new container each iteration; fix by aligning phases—either (A) move
creation of _serviceProvider and _mediatr into the benchmark and have
Initialization_MediatR construct the provider via CreateMediatRServiceProvider()
so both methods build hosts, or (B) create the GFramework runtime once in
Setup() (call CreateGFrameworkRuntime() there and store it, e.g.,
_gframeworkRuntime) and change Initialization_GFrameworkCqrs() to return that
stored ICqrsRuntime so both benchmarks only resolve from an existing host;
update Cleanup() to dispose whichever stored host(s) you choose.
- Around line 118-133: The MediatR and GFramework setups use different
registration patterns causing duplicate handler registrations: in
CreateMediatRServiceProvider the handler is both AddSingleton and
auto-registered via RegisterServicesFromAssembly, while CreateGFrameworkRuntime
manually calls RegisterTransient for the handler; unify them by choosing one
registration strategy for both sides—either switch GFramework to assembly
scanning via RegisterCqrsHandlersFromAssembly or CqrsHandlerRegistryGenerator to
match MediatR’s RegisterServicesFromAssembly, or remove the duplicate
AddSingleton in CreateMediatRServiceProvider and rely only on manual
registrations (or vice versa); also replace the manual RegisterTransient call in
CreateGFrameworkRuntime with the recommended
RegisterCqrsHandlersFromAssembly/CqrsHandlerRegistryGenerator usage to follow
the startup rule.
---
Nitpick comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 57-81: The "最近权威验证" section contains repeated entries of the same
build/check commands (notably the command string `dotnet build
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj -c Release`
repeated six times and `python3 scripts/license-header.py --check` / `git diff
--check` repeated twice); collapse those duplicates by keeping a single
consolidated entry per unique command (e.g., one `dotnet build ... -c Release`
with a combined remark listing added benchmark/regression checkpoints such as
`StreamingBenchmarks`, `RequestPipelineBenchmarks`, `RequestStartupBenchmarks`,
`RequestInvokerBenchmarks`, and `StreamInvokerBenchmarks`) and similarly merge
the duplicate `license-header.py --check` and `git diff --check` lines into
single entries to improve readability while preserving all noted results.
🪄 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: 2a723ee0-1a90-4f18-a03b-ec7b3b0638fc
📒 Files selected for processing (20)
GFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/README.mdGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.csprojGFramework.slnai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
👮 Files not reviewed due to content moderation or server errors (4)
- GFramework.Cqrs.Benchmarks/Messaging/Fixture.cs
- GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
- GFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.cs
- GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.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). (1)
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (12)
**/*[!.]*
📄 CodeRabbit inference engine (AGENTS.md)
For files with shebang lines, keep shebang as first line and place license header immediately after it
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.csprojGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/README.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.sln
**/*.{xml,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
For XML/MSBuild files with XML declaration, keep XML declaration as first node and place license header immediately after it
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.csproj
**/*.csproj
📄 CodeRabbit inference engine (AGENTS.md)
**/*.csproj: Follow repository defaults:ImplicitUsingsdisabled,Nullableenabled,GenerateDocumentationFileenabled for shipped libraries,LangVersiongenerallypreviewin main libraries and abstractions
Minimize new package dependencies. Add them only when necessary and keep scope narrow
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.csproj
**/*.{csproj,cs}
📄 CodeRabbit inference engine (AGENTS.md)
Framework runtime, abstractions, and meta-package projects MUST NOT reference
*.SourceGenerators*projects or packages, and MUST NOT use source-generator attributes
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.csprojGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation. Do not use tabs
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.csprojGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.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 (///) in C#
XML documentation MUST use<summary>,<param>,<returns>,<exception>, and<remarks>where applicable, and explain intent, contract, and usage constraints instead of restating syntax
If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why abstraction exists, and when to use instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Do not rely on implicit imports. Declare every requiredusingexplicitly in C#
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C#
Use namespace patternGFramework.{Module}.{Feature}with PascalCase segments in C#
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, Interfaces useIprefix, Parameters and locals use camelCase, Private fields use_camelCase
Use Allman braces style for C#
Keepusingdirectives at the top of the file and sort them consistently in C#
Prefer one primary type per file unless surrounding project already uses different local pattern
Prefer explicit, readable code over clever shorthand in framework internals
M...
Files:
GFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,ts,tsx,js,jsx,py,sh}: All generated or modified code MUST include clear and meaningful comments where required by documentation rules
Comments MUST NOT be trivial, redundant, or misleading. Prefer explainingwhyandwhen, not justwhat. Code should remain understandable without requiring external context
Avoid obvious comments such as// increment i
Files:
GFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access
Files:
GFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}
📄 CodeRabbit inference engine (AGENTS.md)
Keep line length readable. Around 120 characters is preferred upper bound
Files:
GFramework.Cqrs.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form
Files:
GFramework.Cqrs.Benchmarks/README.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.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.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
**/*{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/RequestStartupBenchmarks.cs
🧠 Learnings (2)
📚 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.Benchmarks/Messaging/Fixture.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Program.csGFramework.Cqrs.Benchmarks/CustomColumn.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedRequestInvokerBenchmarkRegistry.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/GeneratedStreamInvokerBenchmarkRegistry.csGFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs
📚 Learning: 2026-04-16T13:25:59.124Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 235
File: GFramework.SourceGenerators.Tests/Rule/ContextAwareGeneratorSnapshotTests.cs:1-3
Timestamp: 2026-04-16T13:25:59.124Z
Learning: In the GeWuYou/GFramework repo, treat `global using NUnit.Framework;` as provided project-wide by `GFramework.SourceGenerators.Tests/GlobalUsings.cs` (via GlobalUsings.cs). Do not require or flag missing per-file `using NUnit.Framework;` directives in test `.cs` files under `GFramework.SourceGenerators.Tests/`, since the project-wide global usings already include NUnit (along with other common namespaces).
Applied to files:
GFramework.SourceGenerators.Tests/Cqrs/CqrsHandlerRegistryGeneratorTests.cs
🪛 LanguageTool
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
[grammar] ~431-~431: Use a hyphen to join words.
Context: ...registration / service lifetime 或 stream generated provider ### 阶段:stream invoke...
(QB_NEW_EN_HYPHEN)
🔇 Additional comments (6)
GFramework.Cqrs.Benchmarks/README.md (1)
1-46: LGTM — 文档内容与实际引入的文件结构一致。GFramework.sln (1)
53-54: LGTM — 新项目注册格式与现有项目一致,GUID 唯一。GFramework.csproj (1)
77-77: AI 摘要与代码不符:排除规则为新增(而非删除)。摘要描述为"移除了对
GFramework.Cqrs.Benchmarks\**目录的排除",但代码实际在<None Remove>、<Compile Remove>、<EmbeddedResource Remove>三个 ItemGroup 中各新增了一条针对GFramework.Cqrs.Benchmarks\**的排除规则,防止 benchmark 文件被意外打包进元包。代码行为正确,摘要方向相反。GFramework.Cqrs.Benchmarks/Program.cs (1)
1-23: LGTM — 标准的 BenchmarkDotNet 入口实现,文档与命名均规范。GFramework.Cqrs.Benchmarks/CustomColumn.cs (1)
16-71: LGTM —IColumn接口实现完整,nullable 安全,主构造函数参数捕获委托的方式简洁正确。GFramework.Cqrs.Benchmarks/Messaging/BenchmarkContext.cs (1)
8-17: 这个最小上下文拆分是合理的。把 steady-state benchmark 所需的
ICqrsContext降到最小,有助于避免把架构初始化噪音带进 dispatch 对比。
- 修复 RequestStartupBenchmarks 的 baseline 分组、初始化阶段对齐与 MediatR 重复注册问题 - 新增共享 dispatcher cache helper,并统一 benchmark 宿主的 MediatR logging/license 过滤配置 - 更新 cqrs-rewrite 跟踪与 trace,记录 PR #326 锚点、验证去重和 startup benchmark 的残留运行风险
Summary
Test ResultsDetails
Insights
build-and-test: Run #1061
🎉 All tests passed!Slowest Tests
± Comparison with run #1060 at 496ca30 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 25 runs. Github Test Reporter by CTRF 💚 |
- 新增仅支持 workflow_dispatch 的 Benchmark workflow,默认只验证 benchmark 项目 Release build - 补充可选 benchmark_filter 输入与 BenchmarkDotNet 工件上传,支持按场景手动执行基准测试 - 更新 cqrs-rewrite 跟踪与 trace,记录手动 benchmark workflow 的用途与当前 startup benchmark 残留风险
- 新增 BenchmarkHostFactory 统一 benchmark 最小宿主构建,并限制 MediatR 扫描到当前场景所需类型 - 修复 GFramework benchmark 容器未冻结导致的首次 handler 解析缺口,恢复 RequestStartupBenchmarks 冷启动结果 - 优化 request、pipeline、notification、stream 与 invoker benchmark 的生命周期对齐,减少无关程序集扫描噪音 - 更新 cqrs-rewrite 跟踪与追踪文档,记录 PR #326 benchmark review 收敛、根因和验证结果
Summary
Test ResultsDetails
Insights
build-and-test: Run #1062
🎉 All tests passed!Slowest Tests
± Comparison with run #1061 at 94f5d6f | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 26 runs. Github Test Reporter by CTRF 💚 |
There was a problem hiding this comment.
Actionable comments posted: 8
♻️ Duplicate comments (2)
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj (1)
17-20:⚠️ Potential issue | 🟠 Major | ⚡ Quick win[已知问题] MediatR 13.x 许可证日志警告可能污染 benchmark 输出。
过去的 review 已指出:MediatR 13.x 在未配置 License Key 时,会在
LuckyPennySoftware.MediatR.License分类下输出警告日志,干扰 BenchmarkDotNet 控制台输出的可读性。BenchmarkDotNet版本已升至0.15.8,但 MediatR 许可证过滤/配置部分仍需确认是否已在BenchmarkHostFactory或宿主日志配置中处理。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj` around lines 17 - 20, Benchmarks are still emitting MediatR license warnings from the LuckyPennySoftware.MediatR.License logger; update the benchmark host setup (e.g., BenchmarkHostFactory or wherever Host/ILogging is configured) to either set the MediatR license key/environment variable or add a logging filter that suppresses or raises the log level for the LuckyPennySoftware.MediatR.License category so BenchmarkDotNet output is not polluted; search for BenchmarkHostFactory and the host/ILogging configuration code and apply the change there.GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs (1)
133-158:⚠️ Potential issue | 🟠 Major冷启动基准仍然混入了不同的注册策略。
Line 142-145 走的是单点
RegisterTransient,但 Line 154-158 最终会通过AddMediatR(...RegisterServicesFromAssembly(...))扫描程序集。这样ColdStart_*实际同时测了“手工注册 vs 程序集扫描+过滤”的差异,结果不能只解释为 startup / first-hit 成本。这里需要把两边统一到同一种注册路径。As per coding guidelines "**/*{Startup,Init,Register,Setup,Configure}*.cs: 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(...)`."#!/bin/bash # 验证当前 startup benchmark 两侧是否仍在使用不同的注册路径 rg -n -C3 --type=cs 'CreateGFrameworkRuntime\(|RegisterTransient<|CreateMediatRServiceProvider\(|RegisterServicesFromAssembly\(' GFramework.Cqrs.Benchmarks/Messaging🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs` around lines 133 - 158, The cold-start benchmark mixes two registration strategies: CreateGFrameworkRuntime currently registers the handler with RegisterTransient while CreateMediatRServiceProvider relies on AddMediatR(...RegisterServicesFromAssembly...) — unify them by changing GFramework side to use the same assembly-based handler registration pattern required by our guidelines: replace the manual RegisterTransient call inside CreateGFrameworkRuntime with a call to RegisterCqrsHandlersFromAssembly or RegisterCqrsHandlersFromAssemblies (pointing at the assembly that contains BenchmarkRequestHandler / RequestStartupBenchmarks) so both runtimes use generated/assembly-based registration rather than manual per-type registration; ensure any non-default assemblies are explicitly passed to the RegisterCqrsHandlersFromAssembly(s) overload so reflection fallback or generator output is used consistently.
🧹 Nitpick comments (3)
ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (1)
50-126: ⚡ Quick win建议压缩“最近权威验证”到“每类命令仅保留最新一次”
该段目前混合了多轮历史尝试与最新结论,和“唯一权威恢复锚点”定位不完全一致。建议在 active 文档只保留每类命令的最新结果(build/test/run/check 各一条),其余迁移到归档文档并链接。
As per coding guidelines,
Keep code samples, package names, and command examples aligned with current repository state in documentation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md` around lines 50 - 126, Compress the “最近权威验证” section by keeping only the latest result line for each command type (keep one each for dotnet run (benchmarks), dotnet build, dotnet test, python3 scripts/license-header.py --check, and git diff --check) and move all older per-command attempts into an archive/appendix doc with links; update the retained lines to use the canonical command text shown (e.g., the dotnet run --project GFramework.Cqrs.Benchmarks/... --filter "*RequestStartupBenchmarks*" and python3 scripts/license-header.py --check entries) and ensure the summary language and examples align with the repository’s current naming/flags so code samples remain accurate.GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs (2)
56-60: 💤 Low value全局静态
LoggerFactoryResolver.Provider的赋值未做隔离。
Setup中直接覆盖了进程级静态字段LoggerFactoryResolver.Provider,多个 Benchmark 类在同一宿主进程中按 BenchmarkDotNet 调度依次运行时会相互影响,且Cleanup未还原原值。若仅为 benchmark 用途可保留,但建议至少在注释中说明该副作用,或在Cleanup还原原值,避免对其他基准/测试类隐式干扰。♻️ 备选修复
+ private ILoggerFactoryProvider? _previousLoggerProvider; + [GlobalSetup] public void Setup() { + // 备份原 provider,Cleanup 时恢复,避免污染同进程内其他基准。 + _previousLoggerProvider = LoggerFactoryResolver.Provider; LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider { MinLevel = LogLevel.Fatal }; @@ [GlobalCleanup] public void Cleanup() { _serviceProvider.Dispose(); + if (_previousLoggerProvider is not null) + { + LoggerFactoryResolver.Provider = _previousLoggerProvider; + } }As per coding guidelines: "When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs` around lines 56 - 60, The benchmark Setup currently overwrites the process-global LoggerFactoryResolver.Provider (via the call to Fixture.Setup("Request", ...)) without isolation; save the original provider before assigning ConsoleLoggerFactoryProvider (reference LoggerFactoryResolver.Provider) and restore that saved value in the corresponding Cleanup method, or if intentional, add a clear comment in Setup documenting the global side-effect and thread-safety assumptions so other benchmarks running in the same process are not implicitly affected.
65-68: 💤 Low value建议为 GFramework / MediatR 的同名契约引入
using别名以提升可读性。
IRequest/IRequestHandler在两边命名空间冲突,目前通过反复书写完整命名空间来消歧(L65、L68、L122–124、L136–137),可读性受损且容易在日后改动时漏改一处。可在文件顶部用using别名隔离两套契约,使用点保持简洁。♻️ 别名示例
using GFramework.Cqrs.Abstractions.Cqrs; using MediatR; using Microsoft.Extensions.DependencyInjection; +using GfRequest = GFramework.Cqrs.Abstractions.Cqrs.IRequest<GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>; +using GfRequestHandler = GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler< + GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkRequest, + GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>; +using MediatRRequest = MediatR.IRequest<GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>; +using MediatRRequestHandler = MediatR.IRequestHandler< + GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkRequest, + GFramework.Cqrs.Benchmarks.Messaging.RequestBenchmarks.BenchmarkResponse>;注意:因别名需引用嵌套类型,可能需要将
BenchmarkRequest/BenchmarkResponse提升为顶层类型;若不愿改动结构,保持现状亦可。Also applies to: 122-137
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs` around lines 65 - 68, Introduce type/namespace aliases to disambiguate the two IRequest/IRequestHandler families and replace fully-qualified names; e.g. add using GF = GFramework.Cqrs.Abstractions.Cqrs; and using MR = MediatR (or create using GFRequestHandler = GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,BenchmarkResponse> / MRRequestHandler = MediatR.IRequestHandler<BenchmarkRequest,BenchmarkResponse> if you prefer type aliases), then update occurrences of GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest, BenchmarkResponse> (and any plain IRequest/IRequestHandler uses around BenchmarkRequest/BenchmarkResponse at the register and runtime calls) to use the new aliases (e.g., GFRequestHandler or GF.IRequestHandler) so the code is concise and unambiguous while keeping BenchmarkRequest and BenchmarkResponse types consistent.
🤖 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 @.github/workflows/benchmark.yml:
- Around line 54-59: The step "Run filtered benchmarks" currently inlines ${{
inputs.benchmark_filter }} into the shell which enables shell injection;
instead, add an environment variable (e.g., BENCHMARK_FILTER) for that input and
reference it inside the run script with proper double-quotes (use
"$BENCHMARK_FILTER") so the value is passed as an argument to dotnet without
being interpreted by the shell; update the step to set env: BENCHMARK_FILTER:
${{ inputs.benchmark_filter }} and change the run invocation to use --filter
"$BENCHMARK_FILTER" (keep set -euo pipefail and quoting).
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 36-37:
文档中“当前活跃事实”和“最近权威验证”对同一基准(ColdStart_GFrameworkCqrs)结论互相矛盾:更新文档使两处结论一致,采用最新有效结论(即已恢复且不再报错的状态)作为主要显示,将早前记录的
“No CQRS request handler registered”
失败条目标记为已归档或移入归档节并在归档条目中注明时间戳和原因;同时检查并同步文档中的相关命令/示例/包名以反映当前仓库状态,确保在“当前活跃事实”、“最近权威验证”和归档节中只出现一致且有来源的结论(引用
ColdStart_GFrameworkCqrs 和 RequestStartupBenchmarks 来定位修改位置)。
In `@ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md`:
- Around line 259-262: The file contains a duplicated top-level secondary
heading "## 2026-05-06" (first occurrence at the top and again before the block
titled "### 阶段:mixed invoker provider 排序回归(CQRS-REWRITE-RP-083)"), which
triggers MD024; fix it by making the second heading unique—e.g., rename the
repeated "## 2026-05-06" to "## 2026-05-06 (RP-083…RP-089)" or "## 2026-05-06 —
phase: mixed invoker provider" so the header text is distinct and preserves the
related subheading "### 阶段:mixed invoker provider 排序回归(CQRS-REWRITE-RP-083)".
In `@GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs`:
- Around line 85-89: MicrosoftDiContainer currently holds disposable fields
ReaderWriterLockSlim (_lock) and IServiceProvider (_provider) but does not
implement IDisposable, causing resource leaks in benchmarks; implement
IDisposable on MicrosoftDiContainer (in
GFramework.Core/Ioc/MicrosoftDiContainer.cs), add a Dispose method that calls
_lock.Dispose() and, if _provider implements IDisposable, dispose it as well
(and suppress finalization if needed), and then update the benchmark Cleanup to
call Dispose on the _container instead of only disposing the service provider;
do not change CqrsDispatcher/_runtime disposal since it’s unnecessary.
In `@GFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs`:
- Around line 76-96: The MediatR registration in the
CreateMediatRServiceProvider call (_serviceProvider) uses
ServiceLifetime.Singleton which mismatches the Transient lifetime used by the
GFramework reflection (RegisterTransient for ReflectionBenchmarkRequestHandler)
and generated handlers (RegisterCqrsHandlersFromAssembly); change the
ServiceLifetime argument in the CreateMediatRServiceProvider invocation from
ServiceLifetime.Singleton to ServiceLifetime.Transient so MediatR handlers
(e.g., MediatRBenchmarkRequestHandler) are constructed and cached consistently
with the other two paths, or alternatively add a concise comment next to the
CreateMediatRServiceProvider call explaining why Singleton is intentionally
required for this benchmark.
In `@GFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.cs`:
- Around line 59-104: The benchmark leaks dispatcher pipeline chains across
scenarios because dispatcher caches aren’t cleared; add a call to
BenchmarkDispatcherCacheHelper.ClearDispatcherCaches() either at the end of
RequestPipelineBenchmarks.Setup() or at the start of
RequestPipelineBenchmarks.Cleanup() so the dispatcher cache is reset between
runs that reuse the same BenchmarkRequest type (controlled by
RequestPipelineCount) and avoid cross-contamination of
SendRequest_GFrameworkCqrs() results.
- Around line 261-279: The four derived classes BenchmarkPipelineBehavior1,
BenchmarkPipelineBehavior2, BenchmarkPipelineBehavior3 and
BenchmarkPipelineBehavior4 currently use an invalid C# declaration with a
trailing semicolon after the base type; replace the semicolon with an empty type
body (use { } instead of ;) so each class is declared as a sealed class
inheriting BenchmarkPipelineBehaviorBase with an empty body, e.g. public sealed
class BenchmarkPipelineBehavior1 : BenchmarkPipelineBehaviorBase { } and
likewise for the other three classes to restore valid syntax and allow
compilation.
In `@GFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.cs`:
- Around line 76-96: The MediatR handler in StreamInvokerBenchmarks is
registered with ServiceLifetime.Singleton which mismatches the GFramework
registrations (transient) and skews benchmark results; update the call to
BenchmarkHostFactory.CreateMediatRServiceProvider (the invocation that currently
passes ServiceLifetime.Singleton for MediatRBenchmarkStreamHandler) to use
ServiceLifetime.Transient so the MediatR handler lifecycle matches GFramework's
transient handlers, or alternatively extract a separate benchmark targeting
singleton lifecycles if you intentionally want to compare differing lifetimes.
---
Duplicate comments:
In `@GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj`:
- Around line 17-20: Benchmarks are still emitting MediatR license warnings from
the LuckyPennySoftware.MediatR.License logger; update the benchmark host setup
(e.g., BenchmarkHostFactory or wherever Host/ILogging is configured) to either
set the MediatR license key/environment variable or add a logging filter that
suppresses or raises the log level for the LuckyPennySoftware.MediatR.License
category so BenchmarkDotNet output is not polluted; search for
BenchmarkHostFactory and the host/ILogging configuration code and apply the
change there.
In `@GFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.cs`:
- Around line 133-158: The cold-start benchmark mixes two registration
strategies: CreateGFrameworkRuntime currently registers the handler with
RegisterTransient while CreateMediatRServiceProvider relies on
AddMediatR(...RegisterServicesFromAssembly...) — unify them by changing
GFramework side to use the same assembly-based handler registration pattern
required by our guidelines: replace the manual RegisterTransient call inside
CreateGFrameworkRuntime with a call to RegisterCqrsHandlersFromAssembly or
RegisterCqrsHandlersFromAssemblies (pointing at the assembly that contains
BenchmarkRequestHandler / RequestStartupBenchmarks) so both runtimes use
generated/assembly-based registration rather than manual per-type registration;
ensure any non-default assemblies are explicitly passed to the
RegisterCqrsHandlersFromAssembly(s) overload so reflection fallback or generator
output is used consistently.
---
Nitpick comments:
In `@ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md`:
- Around line 50-126: Compress the “最近权威验证” section by keeping only the latest
result line for each command type (keep one each for dotnet run (benchmarks),
dotnet build, dotnet test, python3 scripts/license-header.py --check, and git
diff --check) and move all older per-command attempts into an archive/appendix
doc with links; update the retained lines to use the canonical command text
shown (e.g., the dotnet run --project GFramework.Cqrs.Benchmarks/... --filter
"*RequestStartupBenchmarks*" and python3 scripts/license-header.py --check
entries) and ensure the summary language and examples align with the
repository’s current naming/flags so code samples remain accurate.
In `@GFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.cs`:
- Around line 56-60: The benchmark Setup currently overwrites the process-global
LoggerFactoryResolver.Provider (via the call to Fixture.Setup("Request", ...))
without isolation; save the original provider before assigning
ConsoleLoggerFactoryProvider (reference LoggerFactoryResolver.Provider) and
restore that saved value in the corresponding Cleanup method, or if intentional,
add a clear comment in Setup documenting the global side-effect and
thread-safety assumptions so other benchmarks running in the same process are
not implicitly affected.
- Around line 65-68: Introduce type/namespace aliases to disambiguate the two
IRequest/IRequestHandler families and replace fully-qualified names; e.g. add
using GF = GFramework.Cqrs.Abstractions.Cqrs; and using MR = MediatR (or create
using GFRequestHandler =
GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,BenchmarkResponse>
/ MRRequestHandler = MediatR.IRequestHandler<BenchmarkRequest,BenchmarkResponse>
if you prefer type aliases), then update occurrences of
GFramework.Cqrs.Abstractions.Cqrs.IRequestHandler<BenchmarkRequest,
BenchmarkResponse> (and any plain IRequest/IRequestHandler uses around
BenchmarkRequest/BenchmarkResponse at the register and runtime calls) to use the
new aliases (e.g., GFRequestHandler or GF.IRequestHandler) so the code is
concise and unambiguous while keeping BenchmarkRequest and BenchmarkResponse
types consistent.
🪄 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: 9befa9e4-d103-4a59-aa09-98c6c19c0654
📒 Files selected for processing (13)
.github/workflows/benchmark.ymlGFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.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: Build and Test
- GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (11)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) in C#
XML documentation MUST use<summary>,<param>,<returns>,<exception>, and<remarks>where applicable, and explain intent, contract, and usage constraints instead of restating syntax
If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why abstraction exists, and when to use instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Do not rely on implicit imports. Declare every requiredusingexplicitly in C#
Write null-safe code that respects nullable annotations instead of suppressing warnings by default in C#
Use namespace patternGFramework.{Module}.{Feature}with PascalCase segments in C#
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, Interfaces useIprefix, Parameters and locals use camelCase, Private fields use_camelCase
Use Allman braces style for C#
Keepusingdirectives at the top of the file and sort them consistently in C#
Prefer one primary type per file unless surrounding project already uses different local pattern
Prefer explicit, readable code over clever shorthand in framework internals
M...
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*[!.]*
📄 CodeRabbit inference engine (AGENTS.md)
For files with shebang lines, keep shebang as first line and place license header immediately after it
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,ts,tsx,js,jsx,py,sh}: All generated or modified code MUST include clear and meaningful comments where required by documentation rules
Comments MUST NOT be trivial, redundant, or misleading. Prefer explainingwhyandwhen, not justwhat. Code should remain understandable without requiring external context
Avoid obvious comments such as// increment i
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{csproj,cs}
📄 CodeRabbit inference engine (AGENTS.md)
Framework runtime, abstractions, and meta-package projects MUST NOT reference
*.SourceGenerators*projects or packages, and MUST NOT use source-generator attributes
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation. Do not use tabs
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csprojGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}
📄 CodeRabbit inference engine (AGENTS.md)
Keep line length readable. Around 120 characters is preferred upper bound
Files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
**/*.{xml,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
For XML/MSBuild files with XML declaration, keep XML declaration as first node and place license header immediately after it
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
**/*.csproj
📄 CodeRabbit inference engine (AGENTS.md)
**/*.csproj: Follow repository defaults:ImplicitUsingsdisabled,Nullableenabled,GenerateDocumentationFileenabled for shipped libraries,LangVersiongenerallypreviewin main libraries and abstractions
Minimize new package dependencies. Add them only when necessary and keep scope narrow
Files:
GFramework.Cqrs.Benchmarks/GFramework.Cqrs.Benchmarks.csproj
**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{md,mdx}: Keep code samples, package names, and command examples aligned with current repository state in documentation
When public page references XML docs or API coverage, convert evidence into reader-facing guidance: explain which types/namespaces/entry points readers should inspect and why
For integration-oriented features such as AI-First config system, documentation MUST cover: project directory layout/file conventions, required project/package wiring, minimal working example, migration/compatibility notes
When examples are rewritten, preserve only parts that remain true. Delete or replace speculative examples instead of lightly editing into another inaccurate form
Files:
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.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/RequestStartupBenchmarks.cs
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Cqrs.Benchmarks/Messaging/BenchmarkHostFactory.csGFramework.Cqrs.Benchmarks/Messaging/BenchmarkDispatcherCacheHelper.csGFramework.Cqrs.Benchmarks/Messaging/StreamInvokerBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/StreamingBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestStartupBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestPipelineBenchmarks.csGFramework.Cqrs.Benchmarks/Messaging/RequestInvokerBenchmarks.cs
🪛 LanguageTool
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
[grammar] ~475-~475: Use a hyphen to join words.
Context: ...registration / service lifetime 或 stream generated provider ### 阶段:stream invoke...
(QB_NEW_EN_HYPHEN)
[uncategorized] ~516-~516: The official name of this software platform is spelled with a capital “H”.
Context: ...ark workflow(CQRS-REWRITE-RP-089) - 新增 .github/workflows/benchmark.yml,提供仅 `workflow_...
(GITHUB)
[grammar] ~516-~516: Ensure spelling is correct
Context: ...提供仅 workflow_dispatch 触发的 benchmark 入口 - workflow 默认只执行 GFramework.Cqrs.Benchmarks 的 Re...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🪛 markdownlint-cli2 (0.22.1)
ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md
[warning] 260-260: Multiple headings with the same content
(MD024, no-duplicate-heading)
🔇 Additional comments (1)
GFramework.Cqrs.Benchmarks/Messaging/NotificationBenchmarks.cs (1)
83-87: ⚡ Quick win无需修改
Cleanup()方法 —_container不实现IDisposable。
MicrosoftDiContainer不实现IDisposable接口。其继承链为:MicrosoftDiContainer→ContextAwareBase→IContextAware,均不涉及IDisposable。因此无需在Cleanup()中释放_container。当前代码正确地释放了_serviceProvider(Microsoft.Extensions.DependencyInjection 的ServiceProvider确实实现了IDisposable)。> Likely an incorrect or invalid review comment.
- 修复 benchmark workflow 过滤器输入的 shell 注入风险 - 统一 request 与 stream invoker 基准中 MediatR handler 的生命周期基线 - 更新 request pipeline benchmark 的缓存清理与空行为类型声明 - 压缩 cqrs-rewrite active 跟踪与 trace,记录本轮 PR review 收尾结论
Summary
Test ResultsDetails
Insights
build-and-test: Run #1063
🎉 All tests passed!Slowest Tests
± Comparison with run #1062 at 5aba9a1 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 27 runs. Github Test Reporter by CTRF 💚 |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Summary by CodeRabbit
发布说明
新功能
测试
文档
Chores