mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-06 16:16:44 +08:00
feat(cqrs): 扩大生成式 invoker 发射范围
- 扩大 request 与 stream invoker 发射范围到 reflected-implementation 注册场景 - 补充 hidden implementation 回归测试并更新 CQRS ai-plan 恢复点
This commit is contained in:
parent
172c08176c
commit
eb30388267
@ -23,7 +23,9 @@ public sealed partial class CqrsHandlerRegistryGenerator
|
||||
|
||||
private readonly record struct ReflectedImplementationRegistrationSpec(
|
||||
string HandlerInterfaceDisplayName,
|
||||
string HandlerInterfaceLogName);
|
||||
string HandlerInterfaceLogName,
|
||||
RequestInvokerRegistrationSpec? RequestInvokerRegistration,
|
||||
StreamInvokerRegistrationSpec? StreamInvokerRegistration);
|
||||
|
||||
private readonly record struct OrderedRegistrationSpec(
|
||||
string HandlerInterfaceLogName,
|
||||
|
||||
@ -73,7 +73,7 @@ public sealed partial class CqrsHandlerRegistryGenerator
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 direct handler 注册描述中提取 request invoker 发射计划。
|
||||
/// 从可直接表达 handler 接口的注册描述中提取 request invoker 发射计划。
|
||||
/// </summary>
|
||||
/// <param name="supportsRequestInvokerProvider">
|
||||
/// 指示当前 runtime 是否同时暴露 <c>ICqrsRequestInvokerProvider</c> 与
|
||||
@ -81,7 +81,8 @@ public sealed partial class CqrsHandlerRegistryGenerator
|
||||
/// </param>
|
||||
/// <param name="registrations">已按稳定顺序整理完成的 handler 注册描述。</param>
|
||||
/// <returns>
|
||||
/// 由 <c>directRegistration.RequestInvokerRegistration</c> 派生出的 <see cref="RequestInvokerEmissionSpec" /> 集合。
|
||||
/// 由 direct registration 或 reflected-implementation registration 上的
|
||||
/// <c>RequestInvokerRegistration</c> 派生出的 <see cref="RequestInvokerEmissionSpec" /> 集合。
|
||||
/// <c>methodIndex</c> 按 <paramref name="registrations" /> 与其 direct registration 的遍历顺序单调递增,
|
||||
/// 因而只要上游排序稳定,生成的 invoker 方法名与描述符顺序就跨运行保持稳定。
|
||||
/// </returns>
|
||||
@ -111,13 +112,25 @@ public sealed partial class CqrsHandlerRegistryGenerator
|
||||
directRegistration.HandlerInterfaceDisplayName,
|
||||
methodIndex++));
|
||||
}
|
||||
|
||||
foreach (var reflectedRegistration in registration.ReflectedImplementationRegistrations)
|
||||
{
|
||||
if (reflectedRegistration.RequestInvokerRegistration is not { } requestInvokerRegistration)
|
||||
continue;
|
||||
|
||||
builder.Add(new RequestInvokerEmissionSpec(
|
||||
requestInvokerRegistration.RequestTypeDisplayName,
|
||||
requestInvokerRegistration.ResponseTypeDisplayName,
|
||||
reflectedRegistration.HandlerInterfaceDisplayName,
|
||||
methodIndex++));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 direct handler 注册描述中提取 stream invoker 发射计划。
|
||||
/// 从可直接表达 handler 接口的注册描述中提取 stream invoker 发射计划。
|
||||
/// </summary>
|
||||
/// <param name="supportsStreamInvokerProvider">
|
||||
/// 指示当前 runtime 是否同时暴露 <c>ICqrsStreamInvokerProvider</c> 与
|
||||
@ -125,7 +138,8 @@ public sealed partial class CqrsHandlerRegistryGenerator
|
||||
/// </param>
|
||||
/// <param name="registrations">已按稳定顺序整理完成的 handler 注册描述。</param>
|
||||
/// <returns>
|
||||
/// 由 <c>directRegistration.StreamInvokerRegistration</c> 派生出的 <see cref="StreamInvokerEmissionSpec" /> 集合。
|
||||
/// 由 direct registration 或 reflected-implementation registration 上的
|
||||
/// <c>StreamInvokerRegistration</c> 派生出的 <see cref="StreamInvokerEmissionSpec" /> 集合。
|
||||
/// <c>methodIndex</c> 按 <paramref name="registrations" /> 与其 direct registration 的遍历顺序单调递增,
|
||||
/// 因而只要上游排序稳定,生成的 invoker 方法名与描述符顺序就跨运行保持稳定。
|
||||
/// </returns>
|
||||
@ -151,6 +165,18 @@ public sealed partial class CqrsHandlerRegistryGenerator
|
||||
directRegistration.HandlerInterfaceDisplayName,
|
||||
methodIndex++));
|
||||
}
|
||||
|
||||
foreach (var reflectedRegistration in registration.ReflectedImplementationRegistrations)
|
||||
{
|
||||
if (reflectedRegistration.StreamInvokerRegistration is not { } streamInvokerRegistration)
|
||||
continue;
|
||||
|
||||
builder.Add(new StreamInvokerEmissionSpec(
|
||||
streamInvokerRegistration.RequestTypeDisplayName,
|
||||
streamInvokerRegistration.ResponseTypeDisplayName,
|
||||
reflectedRegistration.HandlerInterfaceDisplayName,
|
||||
methodIndex++));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToImmutable();
|
||||
|
||||
@ -258,7 +258,13 @@ public sealed partial class CqrsHandlerRegistryGenerator : IIncrementalGenerator
|
||||
{
|
||||
reflectedImplementationRegistrations.Add(new ReflectedImplementationRegistrationSpec(
|
||||
handlerInterface.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
GetLogDisplayName(handlerInterface)));
|
||||
GetLogDisplayName(handlerInterface),
|
||||
TryCreateRequestInvokerRegistrationSpec(handlerInterface, out var requestInvokerRegistration)
|
||||
? requestInvokerRegistration
|
||||
: null,
|
||||
TryCreateStreamInvokerRegistrationSpec(handlerInterface, out var streamInvokerRegistration)
|
||||
? streamInvokerRegistration
|
||||
: null));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ CQRS 迁移与收敛。
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`CQRS-REWRITE-RP-068`
|
||||
- 恢复点编号:`CQRS-REWRITE-RP-069`
|
||||
- 当前阶段:`Phase 8`
|
||||
- 当前焦点:
|
||||
- 已完成一轮 `CQRS vs Mediator` 只读评估归档,结论已沉淀到 `archive/todos/cqrs-vs-mediator-assessment-rp063.md`
|
||||
@ -60,6 +60,10 @@ CQRS 迁移与收敛。
|
||||
- `GFramework.SourceGenerators.Tests` 已补充 generator 回归,锁定当 runtime 暴露新契约时,generated registry 会额外发射 stream invoker provider 成员与 invoker 方法
|
||||
- `GFramework.Cqrs/README.md`、`GFramework.Cqrs.SourceGenerators/README.md`、`docs/zh-CN/core/cqrs.md` 与
|
||||
`docs/zh-CN/source-generators/cqrs-handler-registry-generator.md` 现已同步说明 generated stream invoker 的接线与回退边界
|
||||
- 已完成一轮 generated invoker 发射范围补强:
|
||||
- `CqrsHandlerRegistryGenerator` 现会把 generated request / stream invoker 的发射范围,从“仅 direct registration”扩大到“实现类型隐藏、但 handler interface 仍可直接表达”的 reflected-implementation registration
|
||||
- 当前扩展仍刻意避开 `PreciseReflectedRegistrationSpec`,不把隐藏 request/response 类型误拉进 provider 发射,继续保持生成源码可编译边界
|
||||
- `GFramework.SourceGenerators.Tests` 已新增两条 hidden-implementation 回归,锁定 request / stream provider 在该场景下都会继续发射 descriptor 与静态 invoker 方法
|
||||
- 已将 mixed fallback 场景进一步收敛:当 runtime 允许同一程序集声明多个 `CqrsReflectionFallbackAttribute` 实例时,generator 现会把可直接引用的 fallback handlers 与仅能按名称恢复的 fallback handlers 拆分发射
|
||||
- `CqrsReflectionFallbackAttribute` 现允许多实例,以承载 `Type[]` 与字符串 fallback 元数据的组合输出
|
||||
- 已将 generator 的程序集级 fallback 元数据进一步收敛:当全部 fallback handlers 都可直接引用且 runtime 暴露 `params Type[]` 合同时,生成器现优先发射 `typeof(...)` 形式的 fallback 元数据
|
||||
@ -261,6 +265,9 @@ CQRS 迁移与收敛。
|
||||
- `GIT_DIR=/mnt/f/gewuyou/System/Documents/WorkSpace/GameDev/GFramework/.git/worktrees/GFramework-cqrs GIT_WORK_TREE=/mnt/f/gewuyou/System/Documents/WorkSpace/GameDev/GFramework-WorkTree/GFramework-cqrs bash scripts/validate-csharp-naming.sh`
|
||||
- 结果:通过
|
||||
- 备注:`1059` 个 tracked C# 文件命名校验全部通过;本轮新增 stream invoker 类型与测试命名未引入回归
|
||||
- `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Request_Invoker_Provider_Metadata_For_Hidden_Implementation_With_Visible_Interface|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Stream_Invoker_Provider_Metadata_For_Hidden_Implementation_With_Visible_Interface|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Request_Invoker_Provider_Metadata_When_Runtime_Contract_Is_Available|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Stream_Invoker_Provider_Metadata_When_Runtime_Contract_Is_Available"`
|
||||
- 结果:通过
|
||||
- 备注:`4/4` passed;确认 hidden implementation + visible interface 场景也会继续发射 request / stream invoker provider 元数据
|
||||
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release`
|
||||
- 结果:通过
|
||||
- 备注:`0 warning / 0 error`;确认 `CqrsRuntimeModule` 接线变更未引入 `GFramework.Core` 模块构建问题
|
||||
|
||||
@ -58,6 +58,34 @@
|
||||
2. 优先候选仍是 notification 路径是否值得引入同类 generated invoker seam,或继续补强 request / stream provider 的公开 API 入口与诊断语义
|
||||
3. 下一批落地前先提交当前 stream provider 批次,避免未提交改动持续堆叠
|
||||
|
||||
### 阶段:generated invoker reflected-implementation 发射范围补强(CQRS-REWRITE-RP-069)
|
||||
|
||||
- 在 `RP-068` 提交后,重新复算 branch diff,相对 `origin/main` 升至 `20 files / 1015 changed lines`,仍明显低于 `gframework-batch-boot 50` 的 stop condition,因此继续下一批
|
||||
- 本轮目标只收敛 source generator,不扩散到 runtime 或公开文档:把 generated request / stream invoker 的发射范围从“仅 direct registration”扩大到“实现类型隐藏、但 handler interface 可直接表达”的 reflected-implementation registration
|
||||
- 接受只读 subagent 结论后确认:
|
||||
- 现有分类阶段已经为 reflected-implementation registration 保留了 request / stream invoker registration 元数据
|
||||
- 真正缺口只在 `CreateRequestInvokerEmissions(...)` 与 `CreateStreamInvokerEmissions(...)` 仍只遍历 `DirectRegistrations`
|
||||
- `PreciseReflectedRegistrationSpec` 继续排除在 provider 发射范围外,避免隐藏 request/response 类型导致生成源码不可编译
|
||||
- 主线程已完成:
|
||||
- `ReflectedImplementationRegistrationSpec` 显式承载 request / stream invoker registration 元数据
|
||||
- `CreateRequestInvokerEmissions(...)` 与 `CreateStreamInvokerEmissions(...)` 现会同时消费 reflected-implementation registration
|
||||
- `GFramework.SourceGenerators.Tests` 已新增 hidden-implementation + visible-interface 两条 provider 回归
|
||||
- 本轮不改 runtime:dispatcher / registrar 对 generated provider 的消费语义保持不变,变化只在 generator 愿意发射更多可安全静态表达的 descriptor
|
||||
|
||||
### 验证(RP-069)
|
||||
|
||||
- `dotnet build GFramework.Cqrs.SourceGenerators/GFramework.Cqrs.SourceGenerators.csproj -c Release`
|
||||
- 结果:通过,`0 warning / 0 error`
|
||||
- `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Generates_Direct_Interface_Registrations_For_Hidden_Implementation_When_Handler_Interface_Is_Public|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Request_Invoker_Provider_Metadata_When_Runtime_Contract_Is_Available|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Stream_Invoker_Provider_Metadata_When_Runtime_Contract_Is_Available"`
|
||||
- 结果:通过,`3/3` passed
|
||||
- `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --filter "FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Request_Invoker_Provider_Metadata_For_Hidden_Implementation_With_Visible_Interface|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Stream_Invoker_Provider_Metadata_For_Hidden_Implementation_With_Visible_Interface|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Request_Invoker_Provider_Metadata_When_Runtime_Contract_Is_Available|FullyQualifiedName~CqrsHandlerRegistryGeneratorTests.Emits_Stream_Invoker_Provider_Metadata_When_Runtime_Contract_Is_Available"`
|
||||
- 结果:通过,`4/4` passed
|
||||
|
||||
### 当前下一步(RP-069)
|
||||
|
||||
1. 提交当前 generator-only 批次,继续保持每个低风险切片可独立回滚与审查
|
||||
2. 继续评估下一个能明显降低反射占比、但不需要同时改动 runtime 语义的切片
|
||||
|
||||
### 阶段:generated request invoker provider 最小落地(CQRS-REWRITE-RP-067)
|
||||
|
||||
- 继续按 `gframework-batch-boot 50` 执行,基线仍为本地现有 `origin/main`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user