GeWuYou ebdc231c07 docs(sdk): 更新文档规范并添加VitePress配置
- 调整文档真实性原则,以源码和测试为首要证据源
- 新增模块README要求,规定所有用户包必须有说明文档
- 更新仓库文档规范,要求根README与文档站点分类一致
- 添加VitePress配置文件,支持中文搜索和泛型转义
- 创建入门指南文档,说明GFramework模块组成和接入路径
- 添加快速开始教程,演示Core模块最小使用示例
- 为Core模块添加详细README文档
- 为Core.Abstractions添加契约层说明文档
- 为Core.SourceGenerators添加源码生成器文档
- 为Game模块添加运行时层详细说明文档
2026-04-18 10:08:05 +08:00

155 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GFramework.Cqrs
`GFramework.Cqrs` 是 GFramework 的默认 CQRS runtime 包。它在 `GFramework.Cqrs.Abstractions` 之上提供请求分发、通知发布、流式请求处理、处理器注册、上下文扩展方法,以及消息/处理器基类,面向直接使用 GFramework CQRS 的业务模块。
## 模块定位
- 这是 CQRS 的“默认实现层”。
- 包内同时承载运行时基础设施和面向业务代码的便捷基类。
- 它依赖 `GFramework.Cqrs.Abstractions``GFramework.Core.Abstractions`
- 在标准 GFramework 架构启动路径中,`GFramework.Core``CqrsRuntimeModule` 会把默认 runtime、处理器注册器与注册服务自动接入容器。
如果你只需要声明跨模块共享的消息契约,而不想依赖默认 runtime请改为引用 `GeWuYou.GFramework.Cqrs.Abstractions`
## 包关系
推荐的依赖关系如下:
- `GeWuYou.GFramework.Cqrs.Abstractions`
- 最小 CQRS 契约层。
- `GeWuYou.GFramework.Cqrs`
- 默认 runtime 与业务侧常用基类。
- `GeWuYou.GFramework.Cqrs.SourceGenerators`
- 可选。为消费端程序集生成 `ICqrsHandlerRegistry`,运行时优先走生成注册表;缺失或不适用时,回退到反射扫描。
- `GFramework.Core`
- 架构上下文中实际调用 `ICqrsRuntime`,并在模块初始化时注册 CQRS 基础设施。
## 子系统地图
本包当前主要由以下子系统组成:
- 消息基类
- `Command/CommandBase.cs`
- `Query/QueryBase.cs`
- `Request/RequestBase.cs`
- `Notification/NotificationBase.cs`
- 处理器基类
- `Cqrs/CqrsContextAwareHandlerBase.cs`
- `Cqrs/Command/AbstractCommandHandler.cs`
- `Cqrs/Query/AbstractQueryHandler.cs`
- `Cqrs/Notification/AbstractNotificationHandler.cs`
- `Cqrs/Request/AbstractRequestHandler.cs`
- `Cqrs/Request/AbstractStreamRequestHandler.cs`
- `Cqrs/Command/AbstractStreamCommandHandler.cs`
- `Cqrs/Query/AbstractStreamQueryHandler.cs`
- 请求管道
- `Cqrs/Behaviors/LoggingBehavior.cs`
- `Cqrs/Behaviors/PerformanceBehavior.cs`
- 管道契约定义在 `GFramework.Cqrs.Abstractions``IPipelineBehavior<,>`
- 默认 runtime 与注册入口
- `CqrsRuntimeFactory.cs`
- `Internal/CqrsDispatcher.cs`
- `Internal/CqrsHandlerRegistrar.cs`
- `Internal/DefaultCqrsHandlerRegistrar.cs`
- `Internal/DefaultCqrsRegistrationService.cs`
- 生成注册表协作接口
- `ICqrsHandlerRegistry.cs`
- `CqrsHandlerRegistryAttribute.cs`
- `CqrsReflectionFallbackAttribute.cs`
- 业务侧扩展入口
- `Extensions/ContextAwareCqrsExtensions.cs`
- `Extensions/ContextAwareCqrsCommandExtensions.cs`
- `Extensions/ContextAwareCqrsQueryExtensions.cs`
## 最小接入路径
在标准 GFramework 架构中,最小接入通常是“安装包 + 定义消息 + 定义处理器 + 通过上下文发送”:
```bash
dotnet add package GeWuYou.GFramework.Cqrs
dotnet add package GeWuYou.GFramework.Cqrs.Abstractions
```
如果你希望减少处理器注册时的反射扫描,再额外安装:
```bash
dotnet add package GeWuYou.GFramework.Cqrs.SourceGenerators
```
示例:
```csharp
using GFramework.Cqrs.Command;
using GFramework.Cqrs.Cqrs.Command;
using GFramework.Cqrs.Abstractions.Cqrs.Command;
public sealed record CreatePlayerInput(string Name) : ICommandInput;
public sealed class CreatePlayerCommand : CommandBase<CreatePlayerInput, int>
{
public CreatePlayerCommand(CreatePlayerInput input) : base(input)
{
}
}
public sealed class CreatePlayerCommandHandler
: AbstractCommandHandler<CreatePlayerCommand, int>
{
public override ValueTask<int> Handle(
CreatePlayerCommand command,
CancellationToken cancellationToken)
{
var playerModel = Context.GetModel<PlayerModel>();
var playerId = playerModel.Create(command.Input.Name);
return ValueTask.FromResult(playerId);
}
}
```
`IContextAware` 对象内发送命令:
```csharp
using GFramework.Cqrs.Extensions;
var playerId = await this.SendAsync(new CreatePlayerCommand(new CreatePlayerInput("Alice")));
```
`ArchitectureContext` 上也可以直接使用统一 CQRS 入口,例如 `SendRequestAsync``SendQueryAsync``PublishAsync``CreateStream`
## 运行时行为
- 请求分发
- `CqrsDispatcher` 按请求实际类型解析 `IRequestHandler<,>`,未找到处理器会抛出异常。
- 通知分发
- 通知会分发给所有已注册 `INotificationHandler<>`;零处理器时默认静默完成。
- 流式请求
- 通过 `IStreamRequest<TResponse>``IStreamRequestHandler<,>` 返回 `IAsyncEnumerable<TResponse>`
- 上下文注入
- 处理器基类继承 `CqrsContextAwareHandlerBase`runtime 会在分发前注入当前 `IArchitectureContext`
- 如果处理器或行为需要上下文注入,而当前 `ICqrsContext` 不是 `IArchitectureContext`,默认实现会抛出异常。
- 管道行为
- 所有已注册 `IPipelineBehavior<TRequest, TResponse>` 会包裹请求处理器执行。
- 当前包内提供了 `LoggingBehavior``PerformanceBehavior` 两个可复用行为。
## 处理器注册与程序集接入
默认注册流程由 `ICqrsRegistrationService.RegisterHandlers(IEnumerable<Assembly>)` 协调,语义是:
- 同一程序集按稳定键去重,避免重复注册。
- 优先尝试消费端程序集上的 `ICqrsHandlerRegistry` 生成注册器。
- 生成注册器不可用,或声明了 `CqrsReflectionFallbackAttribute` 时,回退到反射扫描。
- 处理器以 transient 方式注册,避免上下文感知处理器在并发请求间共享可变上下文。
如果你走标准 `GFramework.Core` 架构初始化路径,这些步骤通常由框架自动完成;裸容器或测试环境则需要显式补齐 runtime 与注册入口。
## 适用边界
- 这个包是默认实现,不是“纯契约包”。
- 处理器基类依赖 runtime 在分发前注入上下文,不适合脱离 dispatcher 直接手动实例化后调用。
- README 中的消息基类和 handler 基类位于 `GFramework.Cqrs`,接口契约位于 `GFramework.Cqrs.Abstractions`;最小示例通常需要同时引入这两个命名空间层级。
## 文档入口
- 总体文档:`docs/zh-CN/core/cqrs.md`
- 契约层说明:`GFramework.Cqrs.Abstractions/README.md`