feat(cqrs): 补齐流式管道行为接缝#339
Conversation
- 新增 stream pipeline 契约、dispatcher executor 缓存与 generated invoker 兼容路径 - 补充 Architecture 与 IOC 的流式管道注册入口及对应回归测试 - 更新 CQRS 文档和 cqrs-rewrite 的 active tracking/trace
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthrough此PR为CQRS框架添加完整的流式管道行为(stream pipeline behavior)支持,包括新的 ChangesStream Pipeline Behavior Implementation
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 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 #1087
🎉 All tests passed!Slowest Tests
± Comparison with run #1082 at 46d6f48 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 34 runs. Github Test Reporter by CTRF 💚 |
|
| Filename | Overview |
|---|---|
| GFramework.Cqrs/Internal/CqrsDispatcher.cs | Core dispatcher extended to resolve stream behaviors, inject context, cache pipeline executors per behavior count, and build per-dispatch StreamPipelineInvocation chains; logic is correct and well-documented. |
| GFramework.Core/Ioc/MicrosoftDiContainer.cs | Registration logic refactored: common open-generic / closed-interface validation extracted into RegisterCqrsPipelineBehaviorCore; both request and stream registration paths share identical semantics with no duplication. |
| GFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.cs | New interface mirroring IPipelineBehavior for stream requests; contract and documentation are clean. |
| GFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.cs | New delegate type matching the stream pipeline continuation signature; docs clearly describe single-call semantics and cancellation propagation. |
| GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs | Three new stream-pipeline tests cover executor caching, order stability, and context re-injection; TearDown still omits Dispose() on _container (pre-existing P2). |
| GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs | New test verifies generated stream invoker is still preferred and correctly wrapped inside the stream pipeline chain; coverage is adequate. |
| GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs | Smoke regression for the public RegisterCqrsStreamPipelineBehavior architecture surface; DrainAsync helper is clean and InvocationCount reset is symmetric. |
| GFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.cs | Test behavior correctly records per-dispatch context via CqrsContextAwareHandlerBase; singleton registration means _instanceId is stable across dispatches, which matches test assertions. |
Sequence Diagram
sequenceDiagram
participant Caller
participant Architecture
participant ArchitectureModules
participant MicrosoftDiContainer
participant CqrsDispatcher
participant StreamDispatchBinding
participant StreamPipelineExecutor
participant StreamPipelineInvocation
participant Behavior as IStreamPipelineBehavior
participant Handler as IStreamRequestHandler
Note over Architecture,MicrosoftDiContainer: Registration phase
Architecture->>ArchitectureModules: RegisterCqrsStreamPipelineBehavior()
ArchitectureModules->>MicrosoftDiContainer: RegisterCqrsStreamPipelineBehavior()
MicrosoftDiContainer->>MicrosoftDiContainer: RegisterCqrsPipelineBehaviorCore(IStreamPipelineBehavior)
Note over Caller,Handler: Dispatch phase (CreateStream)
Caller->>CqrsDispatcher: CreateStream(context, request, ct)
CqrsDispatcher->>StreamDispatchBinding: GetOrAdd(requestType, responseType)
StreamDispatchBinding-->>CqrsDispatcher: binding
CqrsDispatcher->>MicrosoftDiContainer: Get(HandlerType)
MicrosoftDiContainer-->>CqrsDispatcher: handler
CqrsDispatcher->>CqrsDispatcher: PrepareHandler(handler, context)
CqrsDispatcher->>MicrosoftDiContainer: GetAll(BehaviorType)
MicrosoftDiContainer-->>CqrsDispatcher: behaviors[]
loop each behavior
CqrsDispatcher->>CqrsDispatcher: PrepareHandler(behavior, context)
end
alt "behaviors.Count == 0"
CqrsDispatcher->>Handler: StreamInvoker(handler, request, ct)
else "behaviors.Count > 0"
CqrsDispatcher->>StreamDispatchBinding: GetPipelineExecutor(behaviorCount)
StreamDispatchBinding-->>CqrsDispatcher: StreamPipelineExecutor (cached)
CqrsDispatcher->>StreamPipelineExecutor: Invoke(handler, behaviors, streamInvoker, request, ct)
StreamPipelineExecutor->>StreamPipelineInvocation: new + Invoke(request, ct)
StreamPipelineInvocation->>Behavior: Handle(request, next, ct)
Behavior->>StreamPipelineInvocation: next(request, ct)
StreamPipelineInvocation->>Handler: StreamInvoker(handler, request, ct)
Handler-->>Behavior: IAsyncEnumerable
Behavior-->>Caller: IAsyncEnumerable
end
Reviews (2): Last reviewed commit: "fix(cqrs): 收口 PR339 流式管道评审问题" | Re-trigger Greptile
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| dotnet-format | yes | 1 | no | 4.09s | ||
| ✅ REPOSITORY | gitleaks | yes | no | no | 6.38s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 4.38s |
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
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
GFramework.Cqrs/Internal/CqrsDispatcher.cs (1)
1011-1052: ⚡ Quick win建议补齐
StreamPipelineInvocation.GetContinuation的线程模型说明。
RequestPipelineInvocation.GetContinuation(955–968 行附近)显式记录了 “该缓存仅假定单次分发链按顺序推进;若某个 behavior 并发调用多个 next,这里可能重复创建等价 continuation” 的并发约定,而对称的StreamPipelineInvocation.GetContinuation(1039–1052)只说“保持与 request pipeline 一致的链式语义”,没有把_continuations[index]在并发next()下的语义写明。流式入口比 request 更容易出现并发重入(多 enumerator、上游 behavior 触发多次建流等),把同一段并发说明搬过来对读者更友好,也满足“C# 成员涉及线程行为时必须显式记录”的项目规约。As per coding guidelines: "If a C# member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly".
📝 建议的文档补齐
/// <summary> /// 获取指定阶段的 continuation,并在首次请求时为该阶段绑定一次不可变调用入口。 /// 同一行为多次调用 <c>next</c> 时会命中相同 continuation,保持与 request pipeline 一致的链式语义。 + /// 线程模型上,该缓存仅假定单次建流链按顺序推进;若某个 behavior 并发调用多个 <c>next</c>, + /// 这里可能重复创建等价 continuation,但不会跨建流共享,也不会缓存容器解析出的实例。 /// </summary> private StreamMessageHandlerDelegate<TRequest, TResponse> GetContinuation(int index)🤖 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/Internal/CqrsDispatcher.cs` around lines 1011 - 1052, The GetContinuation method in StreamPipelineInvocation lacks the thread-model doc that RequestPipelineInvocation has; add a summary/remarks on StreamPipelineInvocation.GetContinuation explaining that the _continuations cache is optimistic and assumes a single sequential pipeline progression (multiple concurrent calls to next/Invoke can race and may create equivalent continuation delegates multiple times), that no locking is used, and that this behavior is intentional and safe for stream pipelines; reference the method name GetContinuation, the field _continuations, the types StreamPipelineInvocation<TRequest,TResponse> and StreamPipelineContinuation<TRequest,TResponse>, and mirror the wording/intent used in RequestPipelineInvocation.GetContinuation to satisfy the threading documentation guideline.GFramework.Core/Ioc/MicrosoftDiContainer.cs (1)
481-573: ⚡ Quick win建议提取公共私有方法消除
RegisterCqrsPipelineBehavior与RegisterCqrsStreamPipelineBehavior的代码重复两个方法除了开放泛型接口类型(
IPipelineBehavior<,>vsIStreamPipelineBehavior<,>)和日志/错误消息文本之外,完全相同:锁管理、冻结检查、接口验证和服务注册逻辑全部重复。若后续修改注册生命周期(如从 Singleton 改为 Scoped)或调整验证逻辑,需要同步改动两处,极易遗漏。♻️ 建议的重构:提取私有核心方法
+ /// <summary> + /// 注册 CQRS 管道行为的核心实现。 + /// 封装开放泛型与封闭泛型两种注册路径,供 request pipeline 与 stream pipeline 共同复用, + /// 避免两处注册方法之间的逻辑漂移。 + /// </summary> + /// <typeparam name="TBehavior">行为类型,必须是引用类型。</typeparam> + /// <param name="openGenericInterface"> + /// 要注册的开放泛型管道接口,例如 <c>IPipelineBehavior<,></c> 或 + /// <c>IStreamPipelineBehavior<,></c>。 + /// </param> + /// <param name="interfaceDisplayName">用于错误消息与调试日志的接口展示名称。</param> + private void RegisterCqrsPipelineBehaviorCore<TBehavior>( + Type openGenericInterface, + string interfaceDisplayName) + where TBehavior : class + { + ThrowIfDisposed(); + EnterWriteLockOrThrowDisposed(); + try + { + ThrowIfFrozen(); + + var behaviorType = typeof(TBehavior); + + if (behaviorType.IsGenericTypeDefinition) + { + GetServicesUnsafe.AddSingleton(openGenericInterface, behaviorType); + } + else + { + var pipelineInterfaces = behaviorType + .GetInterfaces() + .Where(type => type.IsGenericType && + type.GetGenericTypeDefinition() == openGenericInterface) + .ToList(); + + if (pipelineInterfaces.Count == 0) + { + var errorMessage = $"{behaviorType.Name} does not implement {interfaceDisplayName}"; + _logger.Error(errorMessage); + throw new InvalidOperationException(errorMessage); + } + + foreach (var pipelineInterface in pipelineInterfaces) + { + GetServicesUnsafe.AddSingleton(pipelineInterface, behaviorType); + } + } + + _logger.Debug($"CQRS {interfaceDisplayName} behavior registered: {behaviorType.Name}"); + } + finally + { + _lock.ExitWriteLock(); + } + } + public void RegisterCqrsPipelineBehavior<TBehavior>() where TBehavior : class - { - ThrowIfDisposed(); - EnterWriteLockOrThrowDisposed(); - try - { - ThrowIfFrozen(); - - var behaviorType = typeof(TBehavior); - - if (behaviorType.IsGenericTypeDefinition) - { - GetServicesUnsafe.AddSingleton(typeof(IPipelineBehavior<,>), behaviorType); - } - else - { - var pipelineInterfaces = behaviorType - .GetInterfaces() - .Where(type => type.IsGenericType && - type.GetGenericTypeDefinition() == typeof(IPipelineBehavior<,>)) - .ToList(); - - if (pipelineInterfaces.Count == 0) - { - var errorMessage = $"{behaviorType.Name} does not implement IPipelineBehavior<,>"; - _logger.Error(errorMessage); - throw new InvalidOperationException(errorMessage); - } - - // 为每个已闭合的管道接口建立显式映射,支持针对特定请求/响应的专用行为。 - foreach (var pipelineInterface in pipelineInterfaces) - { - GetServicesUnsafe.AddSingleton(pipelineInterface, behaviorType); - } - } - - _logger.Debug($"CQRS pipeline behavior registered: {behaviorType.Name}"); - } - finally - { - _lock.ExitWriteLock(); - } - } + => RegisterCqrsPipelineBehaviorCore<TBehavior>(typeof(IPipelineBehavior<,>), "IPipelineBehavior<,>"); public void RegisterCqrsStreamPipelineBehavior<TBehavior>() where TBehavior : class - { - // ... 同上重复逻辑 ... - } + => RegisterCqrsPipelineBehaviorCore<TBehavior>(typeof(IStreamPipelineBehavior<,>), "IStreamPipelineBehavior<,>");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@GFramework.Core/Ioc/MicrosoftDiContainer.cs` around lines 481 - 573, Both RegisterCqrsPipelineBehavior and RegisterCqrsStreamPipelineBehavior duplicate the same locking/validation/registration logic; extract a single private helper that accepts the open-generic interface type (e.g., typeof(IPipelineBehavior<,>) or typeof(IStreamPipelineBehavior<,>), the behaviorType (typeof(TBehavior)), and the textual pieces for logging/error messages, and have both public methods call it. Preserve the existing calls to ThrowIfDisposed, EnterWriteLockOrThrowDisposed, ThrowIfFrozen, _lock.ExitWriteLock(), use GetServicesUnsafe.AddSingleton for registrations, implement the same handling for generic type definitions vs closed interfaces, and rethrow the same InvalidOperationException with the appropriate formatted message when no pipeline interfaces are found.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@GFramework.Core.Abstractions/Ioc/IIocContainer.cs`:
- Around line 108-113: Add XML doc comments to the
RegisterCqrsStreamPipelineBehavior<TBehavior>() member mirroring the other CQRS
registration APIs: keep the existing <summary>, add <typeparam name="TBehavior">
noting it must be a reference type, add <exception> entries documenting that an
InvalidOperationException (or the concrete exception type used elsewhere) is
thrown if the container is frozen/released or the registration is attempted
after disposal, and add a <remarks> block describing intent, thread-safety/usage
constraints and any lifetime/ordering implications so the contract matches other
CQRS registration methods.
In `@GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs`:
- Line 232: Rename the test method
Dispatcher_Should_Cache_Stream_Pipeline_Executors_Per_Bavior_Count to
Dispatcher_Should_Cache_Stream_Pipeline_Executors_Per_Behavior_Count (fix the
misspelling "Bavior" → "Behavior") so it matches the request-side test name;
update the method identifier and any references/usages (e.g., test runner
attributes or other calls) to the new name to keep both tests consistent.
---
Nitpick comments:
In `@GFramework.Core/Ioc/MicrosoftDiContainer.cs`:
- Around line 481-573: Both RegisterCqrsPipelineBehavior and
RegisterCqrsStreamPipelineBehavior duplicate the same
locking/validation/registration logic; extract a single private helper that
accepts the open-generic interface type (e.g., typeof(IPipelineBehavior<,>) or
typeof(IStreamPipelineBehavior<,>), the behaviorType (typeof(TBehavior)), and
the textual pieces for logging/error messages, and have both public methods call
it. Preserve the existing calls to ThrowIfDisposed,
EnterWriteLockOrThrowDisposed, ThrowIfFrozen, _lock.ExitWriteLock(), use
GetServicesUnsafe.AddSingleton for registrations, implement the same handling
for generic type definitions vs closed interfaces, and rethrow the same
InvalidOperationException with the appropriate formatted message when no
pipeline interfaces are found.
In `@GFramework.Cqrs/Internal/CqrsDispatcher.cs`:
- Around line 1011-1052: The GetContinuation method in StreamPipelineInvocation
lacks the thread-model doc that RequestPipelineInvocation has; add a
summary/remarks on StreamPipelineInvocation.GetContinuation explaining that the
_continuations cache is optimistic and assumes a single sequential pipeline
progression (multiple concurrent calls to next/Invoke can race and may create
equivalent continuation delegates multiple times), that no locking is used, and
that this behavior is intentional and safe for stream pipelines; reference the
method name GetContinuation, the field _continuations, the types
StreamPipelineInvocation<TRequest,TResponse> and
StreamPipelineContinuation<TRequest,TResponse>, and mirror the wording/intent
used in RequestPipelineInvocation.GetContinuation to satisfy the threading
documentation guideline.
🪄 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: 318f2573-4ab6-44fa-918b-759b7631a82c
📒 Files selected for processing (31)
GFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Core/Architectures/Architecture.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Abstractions/README.mdGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs/Internal/CqrsDispatcher.csGFramework.Cqrs/README.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mddocs/zh-CN/core/cqrs.md
📜 Review details
🧰 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.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
**/*[!.]*
📄 CodeRabbit inference engine (AGENTS.md)
For files with shebang lines, keep shebang as first line and place license header immediately after it
Files:
GFramework.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/README.mdGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mddocs/zh-CN/core/cqrs.mdGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs/README.mdGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.mdGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.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.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
**/*.{cs,ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{cs,ts,tsx,js,jsx,py}: Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds/compatibility constraints/edge cases, and registration order/lifecycle sequencing/generated code assumptions
Methods with non-trivial logic MUST document core idea, key decisions, and edge case handling
Separate logical blocks with blank lines when it improves readability
Unless there is clear and documented reason to keep file large, keep single source file under roughly 800-1000 lines
Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation, or process boundaries
Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation or allow-listing
Avoid logging secrets, tokens, credentials, or machine-specific sensitive data
Prefer least-privilege behavior for file, process, and environment access
Files:
GFramework.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
**/*.{csproj,cs}
📄 CodeRabbit inference engine (AGENTS.md)
Framework runtime, abstractions, and meta-package projects MUST NOT reference
*.SourceGenerators*projects or packages, and MUST NOT use source-generator attributes
Files:
GFramework.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml,csproj,props,targets}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation. Do not use tabs
Files:
GFramework.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
**/*.{cs,ts,tsx,js,jsx,py,sh,xml}
📄 CodeRabbit inference engine (AGENTS.md)
Keep line length readable. Around 120 characters is preferred upper bound
Files:
GFramework.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
**/*Abstractions/**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
Abstractions projects should only contain interfaces and contract definitions without any runtime implementation logic
Files:
GFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Core.Abstractions/Architectures/IArchitecture.cs
**/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/DispatcherStreamPipelineOrderHandler.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.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.Abstractions/README.mdai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.mddocs/zh-CN/core/cqrs.mdGFramework.Cqrs/README.mdai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.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/cqrs.md
🧠 Learnings (1)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Core/Architectures/Architecture.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.csGFramework.Core.Tests/Architectures/TestArchitectureWithRegistry.csGFramework.Core.Abstractions/Ioc/IIocContainer.csGFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderHandler.csGFramework.Core/Architectures/ArchitectureModules.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineContextRefreshBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.csGFramework.Core/Ioc/MicrosoftDiContainer.csGFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.csGFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.csGFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.csGFramework.Cqrs.Tests/Cqrs/GeneratedStreamPipelineTrackingBehavior.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.csGFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.csGFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.csGFramework.Cqrs.Tests/Cqrs/DispatcherStreamContextRefreshState.csGFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.csGFramework.Core.Abstractions/Architectures/IArchitecture.csGFramework.Cqrs/Internal/CqrsDispatcher.cs
🔇 Additional comments (25)
GFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequest.cs (1)
1-13: LGTM!最小流式请求标记类型实现简洁、文档充分,作为
IStreamPipelineBehavior注册回归测试的输入是合适的最小切片。GFramework.Cqrs.Abstractions/Cqrs/StreamMessageHandlerDelegate.cs (1)
1-23: LGTM!委托签名与变型约束(
in TRequest/out TResponse)与MessageHandlerDelegate<,>对称,并显式记录了短路、单次建流、取消令牌透传等关键语义;作为 abstractions 层契约非常干净。GFramework.Cqrs.Abstractions/Cqrs/IStreamPipelineBehavior.cs (1)
1-26: LGTM!新增的
IStreamPipelineBehavior<TRequest, TResponse>与IPipelineBehavior<,>形态对称,约束统一收敛到IStreamRequest<TResponse>,作为流式 pipeline 的最小契约入口很到位。GFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderRequest.cs (1)
1-11: LGTM!测试用 stream order 请求 record 简洁明确,与同目录内 Outer/Inner/Handler/State fixture 协作的命名也保持一致。
GFramework.Cqrs.Abstractions/README.md (1)
22-22: LGTM!
包关系与子系统地图中已显式列出IStreamPipelineBehavior<,>与StreamMessageHandlerDelegate<,>,与本 PR 新增的 abstractions 入口完全一致。Also applies to: 41-41
GFramework.Core.Tests/Architectures/ModuleStreamBehaviorRequestHandler.cs (1)
13-28: LGTM!
Handle通过yield return 7+ 空await既满足 async 迭代器签名,也产出确定的[7]序列,和ArchitectureModulesBehaviorTests的 stream pipeline 断言形态一致。GFramework.Cqrs/Internal/CqrsDispatcher.cs (4)
144-172: LGTM!
CreateStream的两段式分支(无 behavior 直接走StreamInvoker,有 behavior 走缓存 executor)与SendAsync的请求侧实现完全对称;PrepareHandler在构建 pipeline 之前对所有 behavior 注入上下文,避免了IContextAware行为漏注入。强制转换(IAsyncEnumerable<TResponse>)是StreamInvoker形状受限于object返回时的必要桥接。
628-676: LGTM!
StreamDispatchBinding借助ConcurrentDictionary<int, StreamPipelineExecutor>把 executor 形状按behaviorCount缓存、不缓存 handler/behavior 实例,并通过StreamPipelineExecutorFactoryState把 typed pipeline invoker 透传到工厂避免闭包分配,与RequestDispatchBinding的设计完全对齐;GetPipelineExecutorForTesting这一测试观测面延续了 request 侧的现有约定。
511-528: LGTM!
InvokeStreamPipelineExecutor+StreamPipelineInvoker委托 +StreamPipelineExecutor三件套与 request 侧构造一致;StreamPipelineExecutor.Invoke仍然校验behaviors.Count != BehaviorCount,保留了缓存形状被错误复用时的诊断诊断信号。Also applies to: 546-552, 832-873
1015-1093: LGTM!
StreamPipelineInvocation通过_streamInvoker在最终 handler 调用上保留了 generated stream invoker 的快路径(与RequestPipelineInvocation直接_handler.Handle的取舍不同,这里是必要的,否则 generated 路径在有 behavior 时会被绕过);_continuations数组按behaviors.Count + 1预分配,懒初始化策略与 request 侧一致。ai-plan/public/cqrs-rewrite/todos/cqrs-rewrite-migration-tracking.md (1)
10-12: 💤 Low value确认
当前 PR 锚点所遵循的文档编写约定。第 37-38 行中 RP-099 的描述不含 PR 编号,与 RP-094 至 RP-098 均明确引用
PR#334的模式不一致。第 38 行同时标记 `PR `#334为"下方归档或说明",表示该 PR 正被移至历史参考。第 12 行保留的
当前 PR 锚点:PR#334`` 的含义需要澄清:
- 若该字段指代"当前正在迭代的 review baseline PR",应保留
#334(历史追踪)- 若该字段指代"本次 RP 的 delivery PR",应同步到 RP-099 的实际交付 PR
建议补充注释说明 PR 锚点的约定,或在 RP-099 描述中显式标注其对应 PR,保持后续 RP 条目的一致性。
GFramework.Core.Tests/Architectures/TestArchitectureWithoutRegistry.cs (1)
66-74: LGTM测试替身与现有
RegisterCqrsPipelineBehavior<TBehavior>()存根保持一致,文档注释完整,NotSupportedException语义准确。GFramework.Core/Architectures/ArchitectureModules.cs (1)
30-39: LGTM实现与现有
RegisterCqrsPipelineBehavior<TBehavior>()完全对称,文档齐全,委托链路正确。GFramework.Core.Abstractions/Architectures/IArchitecture.cs (1)
87-94: LGTM接口声明与
RegisterCqrsPipelineBehavior<TBehavior>()完全对称,位于 Abstractions 项目中,无运行时实现,符合抽象层约束。GFramework.Cqrs.Tests/Cqrs/CqrsGeneratedRequestInvokerProviderTests.cs (1)
174-196: LGTM新测试用例结构与现有 generated invoker 测试完全一致:先注册 stream pipeline 行为,再注册 handler,冻结容器后断言结果和调用次数。
Assert.Multiple用法正确,ConfigureAwait(false)使用一致。GFramework.Core.Tests/Architectures/ArchitectureModulesBehaviorTests.cs (1)
97-123: LGTM流式管道行为测试结构与现有
RegisterCqrsPipelineBehavior测试完全对称,finally块正确调用DestroyAsync(),Assert.Multiple同时断言结果值与调用计数。GFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineCacheBehavior.cs (1)
13-29: LGTM最小化直通行为实现正确,
Handle直接转发到下游阶段,不修改流序列,符合用于命中缓存分支的测试意图。文档注释完整。GFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderState.cs (1)
13-13: ⚡ Quick win无需修改。
System.Threading.Lock在 .NET 9.0 及以上版本中可用,该项目的目标框架为net10.0,完全支持此类型。docs/zh-CN/core/cqrs.md (1)
210-222: 新增的流式管道行为文档表述清晰。边界说明(建流级作用域 vs 元素级拦截)以及与
RegisterCqrsPipelineBehavior<TBehavior>()的对比均准确。ai-plan/public/cqrs-rewrite/traces/cqrs-rewrite-migration-trace.md (1)
5-47: RP-099 追踪记录完整。新增阶段描述包含决策原理、测试方向、文档收口和权威验证结果,格式与既有恢复锚点一致。
GFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderOuterBehavior.cs (1)
23-38: 实现正确,包装语义清晰。
[EnumeratorCancellation]+.WithCancellation(cancellationToken)的防御性写法符合 stream behavior 的标准模式;"Outer:Before / Outer:After" 的录制顺序与 onion 包装语义一致。GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherContextValidationTests.cs (1)
92-108: 新增的 stream behavior 上下文校验测试逻辑正确。
PassthroughStreamHandler不继承CqrsContextAwareHandlerBase,ContextAwareStreamBehavior继承,测试有效隔离了 handler 上下文校验与 behavior 上下文校验两个维度。同步断言CreateStream(...)本身抛出也与"建流前显式失败"的语义契约一致。GFramework.Core.Tests/Architectures/TrackingStreamPipelineBehavior.cs (1)
17-27: 线程安全设计正确,静态共享状态已有文档说明。
Interlocked.Increment+Volatile.Read/Write的组合对单整数计数器是充分且正确的。外部调用者通过InvocationCount = 0重置的约束已在 XML 文档中明确声明。GFramework.Cqrs.Tests/Cqrs/DispatcherStreamPipelineOrderInnerBehavior.cs (1)
1-39: LGTM。与
DispatcherStreamPipelineOrderOuterBehavior结构对称,内层录制语义正确。GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs (1)
34-37: Stream pipeline executor 缓存测试覆盖完整。新增的三个测试覆盖了"按 behaviorCount 独立缓存"、"复用缓存时顺序稳定"以及"复用缓存时仍重新注入当前架构上下文"三个关键场景,与 request pipeline 的已有测试形成对称覆盖;
DispatcherStreamPipelineOrderState.Reset()在SetUp中正确添加,避免跨用例状态残留。Also applies to: 228-355, 497-549
- 修复 MicrosoftDiContainer 中 request 与 stream 行为注册逻辑的重复实现并统一校验路径 - 补充流式管道注册入口与 continuation 缓存的 XML 契约说明,明确并发与冻结前调用约束 - 更新 cqrs-rewrite 跟踪文档并修正 ICqrsRequestInvokerProvider 的 XML 缩进格式问题
Summary
Test ResultsDetails
Insights
build-and-test: Run #1088
🎉 All tests passed!Slowest Tests
± Comparison with run #1087 at 40a1d56 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 35 runs. Github Test Reporter by CTRF 💚 |
新增 stream pipeline 契约、dispatcher executor 缓存与 generated invoker 兼容路径
补充 Architecture 与 IOC 的流式管道注册入口及对应回归测试
更新 CQRS 文档和 cqrs-rewrite 的 active tracking/trace
Summary by CodeRabbit
发布说明
新功能
RegisterCqrsStreamPipelineBehavior注册入口,与现有请求管道行为相对应。文档