docs(cqrs): 收口旧版运行时别名说明

- 更新 LegacyICqrsRuntime 兼容层说明,明确旧命名空间别名与正式 CQRS runtime seam 的边界

- 补充容器基础设施回填 legacy alias 的回归测试,并收敛相关 helper 注释

- 更新 cqrs-rewrite 跟踪与 trace,记录 RP-066 的批处理结果和验证
This commit is contained in:
gewuyou 2026-04-30 11:38:52 +08:00
parent c1dfee3c71
commit 7209fdc32d
8 changed files with 126 additions and 11 deletions

View File

@ -26,7 +26,7 @@
| --- | --- | | --- | --- |
| `Architectures/` `Lifecycle/` `Registries/` | `IArchitecture`、上下文、模块、服务模块、阶段监听、注册表基类与生命周期契约 | | `Architectures/` `Lifecycle/` `Registries/` | `IArchitecture`、上下文、模块、服务模块、阶段监听、注册表基类与生命周期契约 |
| `Bases/` `Controller/` `Model/` `Systems/` `Utility/` `Rule/` | 组件角色接口、优先级 / key 值对象、上下文感知约束与扩展边界 | | `Bases/` `Controller/` `Model/` `Systems/` `Utility/` `Rule/` | 组件角色接口、优先级 / key 值对象、上下文感知约束与扩展边界 |
| `Command/` `Query/` `Cqrs/` | 旧版命令 / 查询执行器接口,以及 `ICqrsRuntime` 这类新请求模型接线契约 | | `Command/` `Query/` `Cqrs/` | 旧版命令 / 查询执行器接口,以及面向 CQRS runtime 的兼容别名入口 |
| `Events/` `Property/` `State/` `StateManagement/` | 事件总线、解绑对象、可绑定属性、状态机、Store / reducer / middleware 契约 | | `Events/` `Property/` `State/` `StateManagement/` | 事件总线、解绑对象、可绑定属性、状态机、Store / reducer / middleware 契约 |
| `Coroutine/` `Time/` `Pause/` `Concurrency/` | 协程状态、时间源、暂停栈、键控异步锁和统计对象 | | `Coroutine/` `Time/` `Pause/` `Concurrency/` | 协程状态、时间源、暂停栈、键控异步锁和统计对象 |
| `Resource/` `Pool/` `Logging/` `Localization/` | 资源句柄、对象池、日志、日志工厂、本地化表与格式化契约 | | `Resource/` `Pool/` `Logging/` `Localization/` | 资源句柄、对象池、日志、日志工厂、本地化表与格式化契约 |
@ -41,7 +41,7 @@
| 类型族 | 代表类型 | 阅读重点 | | 类型族 | 代表类型 | 阅读重点 |
| --- | --- | --- | | --- | --- | --- |
| `Architectures/` `Lifecycle/` `Registries/` | `IArchitecture``IArchitectureContext``IServiceModule``KeyValueRegistryBase<TKey, TValue>` | 看架构、上下文、模块装配与注册表基类边界 | | `Architectures/` `Lifecycle/` `Registries/` | `IArchitecture``IArchitectureContext``IServiceModule``KeyValueRegistryBase<TKey, TValue>` | 看架构、上下文、模块装配与注册表基类边界 |
| `Command/` `Query/` `Cqrs/` | `ICommandExecutor``IAsyncQueryExecutor``ICqrsRuntime` | 看命令、查询与新请求模型的调用入口 | | `Command/` `Query/` `Cqrs/` | `ICommandExecutor``IAsyncQueryExecutor``ICqrsRuntime` | 看旧命令 / 查询契约,以及 CQRS runtime 的兼容别名入口 |
| `Events/` `Property/` `State/` `StateManagement/` | `IEventBus``IBindableProperty<T>``IStateMachine``IStore<TState>` | 看事件分发、可绑定状态与 store 契约 | | `Events/` `Property/` `State/` `StateManagement/` | `IEventBus``IBindableProperty<T>``IStateMachine``IStore<TState>` | 看事件分发、可绑定状态与 store 契约 |
| `Coroutine/` `Time/` `Pause/` `Concurrency/` | `IYieldInstruction``ITimeProvider``IPauseStackManager``IAsyncKeyLockManager` | 看协程、时间源、暂停栈与并发协调能力 | | `Coroutine/` `Time/` `Pause/` `Concurrency/` | `IYieldInstruction``ITimeProvider``IPauseStackManager``IAsyncKeyLockManager` | 看协程、时间源、暂停栈与并发协调能力 |
| `Resource/` `Pool/` `Logging/` `Localization/` | `IResourceManager``IObjectPoolSystem``ILogger``ILocalizationManager` | 看资源、对象池、日志与本地化服务角色 | | `Resource/` `Pool/` `Logging/` `Localization/` | `IResourceManager``IObjectPoolSystem``ILogger``ILocalizationManager` | 看资源、对象池、日志与本地化服务角色 |
@ -63,7 +63,11 @@
- 架构与模块入口:`IArchitecture``IArchitectureContext``IServiceModule` - 架构与模块入口:`IArchitecture``IArchitectureContext``IServiceModule`
- 运行时基础设施:`IIocContainer``ILogger``IResourceManager``IConfigurationManager` - 运行时基础设施:`IIocContainer``ILogger``IResourceManager``IConfigurationManager`
- 状态与并发能力:`IStateMachine``IStore``IAsyncKeyLockManager``ITimeProvider` - 状态与并发能力:`IStateMachine``IStore``IAsyncKeyLockManager``ITimeProvider`
- 迁移与组合边界:`ICommandExecutor``IQueryExecutor``ICqrsRuntime` - 迁移与组合边界:`ICommandExecutor``IQueryExecutor`,以及旧命名空间下作为 compatibility alias 暴露的 `ICqrsRuntime`
`GFramework.Core.Abstractions.Cqrs.ICqrsRuntime` 当前主要用于兼容旧命名空间引用。新代码应直接依赖
`GFramework.Cqrs.Abstractions.Cqrs.ICqrsRuntime`这样可以把请求模型、handler 和 runtime seam 保持在同一套
CQRS 契约下。
## 对应文档 ## 对应文档

View File

@ -4,6 +4,7 @@ using GFramework.Core.Ioc;
using GFramework.Core.Logging; using GFramework.Core.Logging;
using GFramework.Core.Tests.Cqrs; using GFramework.Core.Tests.Cqrs;
using GFramework.Core.Tests.Systems; using GFramework.Core.Tests.Systems;
using GFramework.Cqrs;
using GFramework.Cqrs.Abstractions.Cqrs; using GFramework.Cqrs.Abstractions.Cqrs;
using LegacyICqrsRuntime = GFramework.Core.Abstractions.Cqrs.ICqrsRuntime; using LegacyICqrsRuntime = GFramework.Core.Abstractions.Cqrs.ICqrsRuntime;
@ -171,6 +172,30 @@ public class MicrosoftDiContainerTests
Assert.That(_container.Get<ICqrsRuntime>(), Is.SameAs(_container.Get<LegacyICqrsRuntime>())); Assert.That(_container.Get<ICqrsRuntime>(), Is.SameAs(_container.Get<LegacyICqrsRuntime>()));
} }
/// <summary>
/// 测试当容器里仅预注册正式 CQRS runtime seam 时,基础设施接线会补齐 legacy alias
/// 并保持新旧服务类型解析到同一实例。
/// </summary>
[Test]
public void RegisterInfrastructure_Should_Backfill_Legacy_Cqrs_Runtime_Alias_With_The_Same_Instance()
{
_container.Clear();
var runtime = CqrsRuntimeFactory.CreateRuntime(
_container,
LoggerFactoryResolver.Provider.CreateLogger("CqrsDispatcher"));
_container.Register<ICqrsRuntime>(runtime);
Assert.That(_container.Get<LegacyICqrsRuntime>(), Is.Null);
CqrsTestRuntime.RegisterInfrastructure(_container);
Assert.That(_container.GetAll<ICqrsRuntime>(), Has.Count.EqualTo(1));
Assert.That(_container.GetAll<LegacyICqrsRuntime>(), Has.Count.EqualTo(1));
Assert.That(_container.Get<ICqrsRuntime>(), Is.SameAs(runtime));
Assert.That(_container.Get<LegacyICqrsRuntime>(), Is.SameAs(runtime));
}
/// <summary> /// <summary>
/// 测试当没有实例时获取应返回 null 的功能 /// 测试当没有实例时获取应返回 null 的功能
/// </summary> /// </summary>

View File

@ -32,6 +32,8 @@ public sealed class CqrsRuntimeModule : IServiceModule
/// <summary> /// <summary>
/// 注册默认 CQRS runtime seam 实现。 /// 注册默认 CQRS runtime seam 实现。
/// 该入口会同时补齐旧命名空间下的 <c>ICqrsRuntime</c> 兼容别名,
/// 并保证新旧服务类型都解析到同一个 runtime 实例。
/// </summary> /// </summary>
/// <param name="container">目标依赖注入容器。</param> /// <param name="container">目标依赖注入容器。</param>
public void Register(IIocContainer container) public void Register(IIocContainer container)
@ -46,12 +48,26 @@ public sealed class CqrsRuntimeModule : IServiceModule
var registrar = CqrsRuntimeFactory.CreateHandlerRegistrar(container, registrarLogger); var registrar = CqrsRuntimeFactory.CreateHandlerRegistrar(container, registrarLogger);
container.Register(runtime); container.Register(runtime);
container.Register<LegacyICqrsRuntime>((LegacyICqrsRuntime)runtime); RegisterLegacyRuntimeAlias(container, runtime);
container.Register<ICqrsHandlerRegistrar>(registrar); container.Register<ICqrsHandlerRegistrar>(registrar);
container.Register<ICqrsRegistrationService>( container.Register<ICqrsRegistrationService>(
CqrsRuntimeFactory.CreateRegistrationService(registrar, registrationLogger)); CqrsRuntimeFactory.CreateRegistrationService(registrar, registrationLogger));
} }
/// <summary>
/// 为旧命名空间下的 CQRS runtime 契约注册兼容别名。
/// </summary>
/// <param name="container">承载运行时实例的依赖注入容器。</param>
/// <param name="runtime">当前已创建的新 CQRS runtime 实例。</param>
/// <remarks>
/// 旧接口仍作为兼容入口保留,因此这里明确把别名注册收敛到单独 helper
/// 便于后续独立评估 alias 收口,而不混入 runtime 主体行为。
/// </remarks>
private static void RegisterLegacyRuntimeAlias(IIocContainer container, ICqrsRuntime runtime)
{
container.Register<LegacyICqrsRuntime>((LegacyICqrsRuntime)runtime);
}
/// <summary> /// <summary>
/// 初始化模块。 /// 初始化模块。
/// </summary> /// </summary>

View File

@ -52,6 +52,8 @@ public static class CqrsTestRuntime
/// 这使仅使用 <see cref="MicrosoftDiContainer" /> 的测试环境也能观察与生产路径一致的 runtime 行为, /// 这使仅使用 <see cref="MicrosoftDiContainer" /> 的测试环境也能观察与生产路径一致的 runtime 行为,
/// 而无需完整启动服务模块管理器。 /// 而无需完整启动服务模块管理器。
/// 该方法按服务类型执行幂等注册,只会补齐当前容器中尚未接线的 CQRS 基础设施。 /// 该方法按服务类型执行幂等注册,只会补齐当前容器中尚未接线的 CQRS 基础设施。
/// 若容器里只预注册了正式 <see cref="ICqrsRuntime" /> seam本方法也会补齐旧命名空间下的
/// <see cref="LegacyICqrsRuntime" /> 兼容别名,并保持它与正式 seam 指向同一实例。
/// </remarks> /// </remarks>
public static void RegisterInfrastructure(MicrosoftDiContainer container) public static void RegisterInfrastructure(MicrosoftDiContainer container)
{ {
@ -63,11 +65,11 @@ public static class CqrsTestRuntime
var notificationPublisher = container.Get<INotificationPublisher>(); var notificationPublisher = container.Get<INotificationPublisher>();
var runtime = CqrsRuntimeFactory.CreateRuntime(container, runtimeLogger, notificationPublisher); var runtime = CqrsRuntimeFactory.CreateRuntime(container, runtimeLogger, notificationPublisher);
container.Register(runtime); container.Register(runtime);
container.Register<LegacyICqrsRuntime>((LegacyICqrsRuntime)runtime); RegisterLegacyRuntimeAlias(container, runtime);
} }
else if (container.Get<LegacyICqrsRuntime>() is null) else if (container.Get<LegacyICqrsRuntime>() is null)
{ {
container.Register<LegacyICqrsRuntime>((LegacyICqrsRuntime)container.GetRequired<ICqrsRuntime>()); RegisterLegacyRuntimeAlias(container, container.GetRequired<ICqrsRuntime>());
} }
if (container.Get<ICqrsHandlerRegistrar>() is null) if (container.Get<ICqrsHandlerRegistrar>() is null)
@ -86,6 +88,19 @@ public static class CqrsTestRuntime
} }
} }
/// <summary>
/// 为旧命名空间下的 CQRS runtime 契约注册兼容别名。
/// </summary>
/// <param name="container">承载运行时实例的测试容器。</param>
/// <param name="runtime">当前正式 CQRS runtime 实例。</param>
/// <remarks>
/// 测试辅助层显式保留这条 helper避免“已存在正式 seam 时再补旧别名”的兼容语义分散在多个分支里。
/// </remarks>
private static void RegisterLegacyRuntimeAlias(MicrosoftDiContainer container, ICqrsRuntime runtime)
{
container.Register<LegacyICqrsRuntime>((LegacyICqrsRuntime)runtime);
}
/// <summary> /// <summary>
/// 通过与生产代码一致的注册入口扫描并注册指定程序集中的 CQRS 处理器。 /// 通过与生产代码一致的注册入口扫描并注册指定程序集中的 CQRS 处理器。
/// </summary> /// </summary>

View File

@ -7,7 +7,7 @@ CQRS 迁移与收敛。
## 当前恢复点 ## 当前恢复点
- 恢复点编号:`CQRS-REWRITE-RP-065` - 恢复点编号:`CQRS-REWRITE-RP-066`
- 当前阶段:`Phase 8` - 当前阶段:`Phase 8`
- 当前焦点: - 当前焦点:
- 已完成一轮 `CQRS vs Mediator` 只读评估归档,结论已沉淀到 `archive/todos/cqrs-vs-mediator-assessment-rp063.md` - 已完成一轮 `CQRS vs Mediator` 只读评估归档,结论已沉淀到 `archive/todos/cqrs-vs-mediator-assessment-rp063.md`
@ -34,6 +34,12 @@ CQRS 迁移与收敛。
`Mediator` 语义收口为 `CQRS` / `ArchitectureContext` `Mediator` 语义收口为 `CQRS` / `ArchitectureContext`
- 已补充 `ArchitectureContextTests` 并发 lazy-resolution 回归,锁定 `PublishAsync(...)``CreateStream(...)` - 已补充 `ArchitectureContextTests` 并发 lazy-resolution 回归,锁定 `PublishAsync(...)``CreateStream(...)`
在并发首次访问时也只会解析一次 `ICqrsRuntime` 在并发首次访问时也只会解析一次 `ICqrsRuntime`
- 已完成一轮 `LegacyICqrsRuntime` compatibility slice 收口:
- `CqrsRuntimeModule``GFramework.Tests.Common.CqrsTestRuntime` 现把 legacy alias 注册收敛到显式 helper
- `MicrosoftDiContainerTests` 已补充“只预注册正式 `ICqrsRuntime` seam 时,也会回填 legacy alias 且保持同实例”的回归
- `GFramework.Core.Abstractions/README.md``docs/zh-CN/abstractions/core-abstractions.md`
`docs/zh-CN/core/cqrs.md` 现已明确:旧命名空间下的 `ICqrsRuntime` 仅作为 compatibility alias 保留,
新代码应直接依赖 `GFramework.Cqrs.Abstractions.Cqrs.ICqrsRuntime`
- 已将 mixed fallback 场景进一步收敛:当 runtime 允许同一程序集声明多个 `CqrsReflectionFallbackAttribute` 实例时generator 现会把可直接引用的 fallback handlers 与仅能按名称恢复的 fallback handlers 拆分发射 - 已将 mixed fallback 场景进一步收敛:当 runtime 允许同一程序集声明多个 `CqrsReflectionFallbackAttribute` 实例时generator 现会把可直接引用的 fallback handlers 与仅能按名称恢复的 fallback handlers 拆分发射
- `CqrsReflectionFallbackAttribute` 现允许多实例,以承载 `Type[]` 与字符串 fallback 元数据的组合输出 - `CqrsReflectionFallbackAttribute` 现允许多实例,以承载 `Type[]` 与字符串 fallback 元数据的组合输出
- 已将 generator 的程序集级 fallback 元数据进一步收敛:当全部 fallback handlers 都可直接引用且 runtime 暴露 `params Type[]` 合同时,生成器现优先发射 `typeof(...)` 形式的 fallback 元数据 - 已将 generator 的程序集级 fallback 元数据进一步收敛:当全部 fallback handlers 都可直接引用且 runtime 暴露 `params Type[]` 合同时,生成器现优先发射 `typeof(...)` 形式的 fallback 元数据
@ -216,6 +222,12 @@ CQRS 迁移与收敛。
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~MicrosoftDiContainerTests"` - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~MicrosoftDiContainerTests"`
- 结果:通过 - 结果:通过
- 备注:`41/41` 通过;确认 CQRS 基础设施默认接线与容器行为未回归 - 备注:`41/41` 通过;确认 CQRS 基础设施默认接线与容器行为未回归
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~MicrosoftDiContainerTests"`
- 结果:通过
- 备注:`42/42` 通过;本轮新增 legacy alias 回填回归后,确认正式 seam 与旧命名空间 alias 仍指向同一实例
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release`
- 结果:通过
- 备注:`0 warning / 0 error`;确认 legacy alias helper 收敛与文档更新未引入 `GFramework.Core` 模块构建告警
- `dotnet build GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release` - `dotnet build GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release`
- 结果:通过 - 结果:通过
- 备注:`0 warning / 0 error`;确认三份 `Mediator` 命名收口后的 CQRS 测试项目构建仍然干净 - 备注:`0 warning / 0 error`;确认三份 `Mediator` 命名收口后的 CQRS 测试项目构建仍然干净
@ -226,5 +238,5 @@ CQRS 迁移与收敛。
## 下一步 ## 下一步
1. 基于已落地的 notification publisher seam评估是否需要第二阶段公开配置面、并行 publisher 或 telemetry decorator 1. 基于已落地的 notification publisher seam评估是否需要第二阶段公开配置面、并行 publisher 或 telemetry decorator
2. 继续以 `dispatch/invoker` 生成前移为优先对象,补一轮面向实现的设计评估 2. 继续以 `dispatch/invoker` 生成前移为优先对象,优先尝试 “generated request invoker provider + dispatcher fallback” 这条最小实现切片
3. 单独规划旧 `Command` / `Query` API `LegacyICqrsRuntime` 的收口顺序;`Mediator` 测试命名收口已完成,可移出该子问题 3. 单独规划旧 `Command` / `Query` API 的收口顺序;`LegacyICqrsRuntime` compatibility slice 已收口到显式 helper 与专门测试,可暂时移出最高优先级

View File

@ -2,6 +2,37 @@
## 2026-04-30 ## 2026-04-30
### 阶段LegacyICqrsRuntime compatibility slice 收口CQRS-REWRITE-RP-066
- 继续按 `gframework-batch-boot 50` 执行,基线仍为本地现有 `origin/main`
- 在 `RP-065` 之后复算 branch diff相对 `origin/main` 仍为 `19 files`,明显低于 `50 files` stop condition因此继续下一批
- 本轮按“关键路径本地、非冲突文档委派”的方式拆成两个切片:
- worker`GFramework.Core.Abstractions/README.md``docs/zh-CN/abstractions/core-abstractions.md``docs/zh-CN/core/cqrs.md`
- 主线程:`GFramework.Core/Services/Modules/CqrsRuntimeModule.cs``GFramework.Tests.Common/CqrsTestRuntime.cs``GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs`
- 接受只读 subagent 结论后,将 `LegacyICqrsRuntime` 定位为“容器兼容层”,明确本轮不删除别名、不改 dispatcher 主体、不与旧 `Command` / `Query` API 清理混做
- 主线程已完成:
- `CqrsRuntimeModule` 把 legacy alias 注册收敛到 `RegisterLegacyRuntimeAlias(...)` helper并在 XML 文档里明确新旧服务类型解析到同一 runtime 实例
- `CqrsTestRuntime.RegisterInfrastructure(...)` 现也通过同名 helper 补齐 legacy alias当容器只预注册正式 `ICqrsRuntime` seam 时,会在幂等接线时回填旧命名空间 alias
- `MicrosoftDiContainerTests` 新增 `RegisterInfrastructure_Should_Backfill_Legacy_Cqrs_Runtime_Alias_With_The_Same_Instance`,锁定“只存在正式 seam 时也会补旧 alias且两者仍指向同一实例”的兼容合同
- worker 已完成文档收口:
- `GFramework.Core.Abstractions/README.md`
- `docs/zh-CN/abstractions/core-abstractions.md`
- `docs/zh-CN/core/cqrs.md`
- 三处文档都已明确:`GFramework.Core.Abstractions.Cqrs.ICqrsRuntime` 只是旧命名空间下保留的 compatibility alias新代码应依赖 `GFramework.Cqrs.Abstractions.Cqrs.ICqrsRuntime`
### 验证
- `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~MicrosoftDiContainerTests"`
- 结果:通过,`42/42` passed
- `dotnet build GFramework.Core/GFramework.Core.csproj -c Release`
- 结果:通过,`0 warning / 0 error`
### 当前下一步
1. 在保持 branch diff 低于阈值的前提下,回到 `dispatch/invoker` 生成前移主线
2. 优先尝试只覆盖 request 路径的 generated invoker/provider 最小切片,避免一次卷入 notification / stream / pipeline executor
3. 下一次 batch 结束后继续复算 branch diff确认距 `50 files` stop condition 的剩余 headroom
### 阶段:测试命名收口与 ArchitectureContext lazy-resolution 回归CQRS-REWRITE-RP-065 ### 阶段:测试命名收口与 ArchitectureContext lazy-resolution 回归CQRS-REWRITE-RP-065
- 继续按 `gframework-batch-boot 50` 执行,基线仍为本地现有 `origin/main` - 继续按 `gframework-batch-boot 50` 执行,基线仍为本地现有 `origin/main`

View File

@ -75,7 +75,10 @@ public sealed class DiagnosticsFeature
- 架构与模块入口:`IArchitecture``IArchitectureContext``IServiceModule` - 架构与模块入口:`IArchitecture``IArchitectureContext``IServiceModule`
- 运行时基础设施:`IIocContainer``ILogger``IResourceManager``IConfigurationManager` - 运行时基础设施:`IIocContainer``ILogger``IResourceManager``IConfigurationManager`
- 状态与并发能力:`IStateMachine``IStore``IAsyncKeyLockManager``ITimeProvider` - 状态与并发能力:`IStateMachine``IStore``IAsyncKeyLockManager``ITimeProvider`
- 迁移与组合边界:`ICommandExecutor``IQueryExecutor``ICqrsRuntime` - 迁移与组合边界:`ICommandExecutor``IQueryExecutor`,以及旧命名空间下作为 compatibility alias 暴露的 `ICqrsRuntime`
`GFramework.Core.Abstractions.Cqrs.ICqrsRuntime` 当前主要承担旧命名空间兼容入口的角色。编写新模块或新增请求处理逻辑时,
应直接引用 `GFramework.Cqrs.Abstractions.Cqrs.ICqrsRuntime`,让 runtime seam 与 CQRS 请求契约保持一致。
## 契约族阅读入口 ## 契约族阅读入口
@ -85,7 +88,7 @@ public sealed class DiagnosticsFeature
| --- | --- | --- | | --- | --- | --- |
| `Architectures/` | `IArchitecture``IArchitectureContext``IArchitectureServices``IServiceModule` | 架构上下文、服务访问面与模块安装 / 生命周期约束 | | `Architectures/` | `IArchitecture``IArchitectureContext``IArchitectureServices``IServiceModule` | 架构上下文、服务访问面与模块安装 / 生命周期约束 |
| `Lifecycle/` `Registries/` | `ILifecycle``IAsyncInitializable``IRegistry<T, TR>``KeyValueRegistryBase<TKey, TValue>` | 初始化 / 销毁阶段和注册表抽象边界 | | `Lifecycle/` `Registries/` | `ILifecycle``IAsyncInitializable``IRegistry<T, TR>``KeyValueRegistryBase<TKey, TValue>` | 初始化 / 销毁阶段和注册表抽象边界 |
| `Command/` `Query/` `Cqrs/` | `ICommandExecutor``IAsyncCommand<TResult>``IQueryExecutor``ICqrsRuntime` | 旧命令 / 查询接口与新请求模型之间的兼容和迁移边界 | | `Command/` `Query/` `Cqrs/` | `ICommandExecutor``IAsyncCommand<TResult>``IQueryExecutor``ICqrsRuntime` | 旧命令 / 查询接口,以及 CQRS runtime compatibility alias 的迁移边界 |
| `Events/` `Property/` | `IEventBus``IEventFilter<T>``IBindableProperty<T>``IReadonlyBindableProperty<T>` | 事件传播、过滤、解绑对象和属性订阅语义 | | `Events/` `Property/` | `IEventBus``IEventFilter<T>``IBindableProperty<T>``IReadonlyBindableProperty<T>` | 事件传播、过滤、解绑对象和属性订阅语义 |
| `State/` `StateManagement/` | `IStateMachine``IAsyncState``IStore<TState>``IStoreMiddleware<TState>` | 状态机契约与 Store 的 reducer / middleware / diagnostics 边界 | | `State/` `StateManagement/` | `IStateMachine``IAsyncState``IStore<TState>``IStoreMiddleware<TState>` | 状态机契约与 Store 的 reducer / middleware / diagnostics 边界 |
| `Coroutine/` `Time/` `Pause/` `Concurrency/` | `IYieldInstruction``ICoroutineStatistics``ITimeProvider``IPauseStackManager``IAsyncKeyLockManager` | 调度模型、时间源、暂停栈和异步锁契约 | | `Coroutine/` `Time/` `Pause/` `Concurrency/` | `IYieldInstruction``ICoroutineStatistics``ITimeProvider``IPauseStackManager``IAsyncKeyLockManager` | 调度模型、时间源、暂停栈和异步锁契约 |

View File

@ -13,6 +13,9 @@ description: Cqrs 模块族的运行时、契约层、生成器入口,以及
如果你在写新功能,优先使用这套请求模型,而不是继续扩展 `GFramework.Core.Command` / `Query` 的兼容层。 如果你在写新功能,优先使用这套请求模型,而不是继续扩展 `GFramework.Core.Command` / `Query` 的兼容层。
如果你在查找 `ICqrsRuntime`,请把 `GFramework.Core.Abstractions.Cqrs.ICqrsRuntime` 理解为旧命名空间下保留的
legacy compatibility alias。新代码应直接依赖 `GFramework.Cqrs.Abstractions.Cqrs.ICqrsRuntime`
## 模块族边界 ## 模块族边界
| 模块 | 角色 | 何时安装 | | 模块 | 角色 | 何时安装 |
@ -202,6 +205,12 @@ RegisterCqrsPipelineBehavior<LoggingBehavior<,>>();
`IArchitectureContext` 仍然兼容旧入口,但新代码应优先使用 CQRS runtime。 `IArchitectureContext` 仍然兼容旧入口,但新代码应优先使用 CQRS runtime。
这里有两个边界需要分开理解:
- 旧 `Command` / `Query` 入口仍可用于维护历史调用链
- 旧命名空间下的 `ICqrsRuntime` 只是为了兼容既有引用而保留的 alias面向新代码时应直接使用
`GFramework.Cqrs.Abstractions.Cqrs.ICqrsRuntime`
一个简单判断规则: 一个简单判断规则:
- 在维护历史代码:允许继续使用旧 Command / Query - 在维护历史代码:允许继续使用旧 Command / Query