笔记本
This commit is contained in:
parent
47cd146a5a
commit
96efda9aaf
128
notes/helloshop/ordering-service.md
Normal file
128
notes/helloshop/ordering-service.md
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# 使用 CQRS 模式实现订单服务
|
||||||
|
|
||||||
|
CQRS 是命令和查询责任分离的英文缩写,它是一种将读取操作和更新操作分离的模式,查询返回结果,不改变系统的状态,没有副作用。命令执行更改系统状态,幂等性是指相同的命令多次执行,结果是一样的,不会有副作用。
|
||||||
|
|
||||||
|
|
||||||
|
## 为什么要使用 CQRS 模式
|
||||||
|
|
||||||
|
在传统的体系结构中,使用同一数据模型查询和更新数据库。 这十分简单,非常适用于基本的 CRUD 操作。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
CQRS 将读取和写入分离到不同的模型,使用命令来更新数据,使用查询来读取数据。读取存储可以是写入存储的只读副本,或者读取和写入存储可以具有完全不同的结构。 使用多个只读副本可以提高查询性能,尤其是在只读副本靠近应用程序实例的分布式方案中。
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 使用 MediatR 实现 CQRS 中的 Command 模式
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotnet add package MediatR
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class CreateOrderCommand : IRequest<bool>
|
||||||
|
{
|
||||||
|
public string Product { get; set; }
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateOrderCommandHandler1 : IRequestHandler<CreateOrderCommand, bool>
|
||||||
|
{
|
||||||
|
public Task<bool> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return Task.FromResult(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateOrderCommandHandler2 : IRequestHandler<CreateOrderCommand, bool>
|
||||||
|
{
|
||||||
|
public Task<bool> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return Task.FromResult(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
|
||||||
|
public class OrdersController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public OrdersController(IMediator mediator)
|
||||||
|
{
|
||||||
|
_mediator = mediator;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> CreateOrder(CreateOrderCommand command)
|
||||||
|
{
|
||||||
|
var orderId = await _mediator.Send(command);
|
||||||
|
return Ok(orderId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
builder.Services.AddMediatR(options => options.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用 Mediator 请求管道处理 CQRS 中的命令
|
||||||
|
|
||||||
|
`LoggingBehavior`、`ValidatorBehavior` 和 `TransactionBehavior`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
builder.Services.AddMediatR(options =>
|
||||||
|
{
|
||||||
|
options.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
|
||||||
|
options.AddOpenBehavior(typeof(LoggingBehavior<,>));
|
||||||
|
options.AddOpenBehavior(typeof(ValidatorBehavior<,>));
|
||||||
|
options.AddOpenBehavior(typeof(TransactionBehavior<,>));
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
或者使用 `Pipeline` 扩展方法
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
|
||||||
|
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>));
|
||||||
|
builder.Services.AddScoped(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 实现 CQRS 中的 Query 模式
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public interface IOrderQueries
|
||||||
|
{
|
||||||
|
Task<OrderDetails> GetOrderAsync(int id);
|
||||||
|
|
||||||
|
Task<IEnumerable<OrderSummary>> GetOrdersFromUserAsync(int userId);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
builder.Services.AddScoped<IOrderQueries,OrderQueries>();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用 Dapr.AspNetCore 处理集成事件
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotnet add package Dapr.AspNetCore
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
services.AddDaprClient();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
https://learn.microsoft.com/zh-cn/azure/architecture/patterns/cqrs
|
||||||
|
|
||||||
|
https://learn.microsoft.com/zh-cn/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns
|
||||||
|
|
||||||
|
https://www.xcode.me/Training?keyword=cqrs
|
Loading…
Reference in New Issue
Block a user