当前位置: 首页 > news >正文

(二)毛子整洁架构(CQRS/Dapper/DomianEvent Handler)


文章目录

  • 项目地址
  • 一、Application 层
    • 1.1 定义CQRS的接口以及其他服务
      • 1. Command
      • 2. IQuery查询
      • 3. 当前时间服务接口
      • 4. 邮件发送服务接口
    • 1.2 ReserveBooking Command
      • 1. 处理传入的参数
      • 2. ReserveBookingCommandHandler
      • 3. BookingReservedDomainEvent
    • 1.3 GetBooking Query
      • 1. 创建Dapper的链接接口


项目地址

  • 教程作者:
  • 教程地址:
  • 代码仓库地址:
  • 所用到的框架和插件:
dbt 
airflow

一、Application 层

1.1 定义CQRS的接口以及其他服务

在这里插入图片描述

1. Command

  • 用于处理除查询以外的
  1. ICommand.cs
using Bookify.Domain.Abstractions;
using MediatR;
namespace Bookify.Application.Abstractions.Messaging;
//无返回值的命令
public interface ICommand : IRequest<Result>
{
}
//返回一个TReponse的命令
public interface ICommand<TReponse> : IRequest<Result<TReponse>>
{
}
  1. ICommandHandler.cs
namespace Bookify.Application.Abstractions.Messaging;
public interface ICommandHandler<TCommand> : IRequestHandler<TCommand, Result>where TCommand : ICommand
{
}public interface ICommandHandler<TCommand, TResponse> : IRequestHandler<TCommand, Result<TResponse>>where TCommand : ICommand<TResponse>
{
}

2. IQuery查询

  • 用于查询
    IQuery.cs
using Bookify.Domain.Abstractions;
using MediatR;
namespace Bookify.Application.Abstractions.Messaging;
public interface IQuery<TResponse> : IRequest<Result<TResponse>>
{
}
  • IQueryHandler.cs
using Bookify.Domain.Abstractions;
using MediatR;
namespace Bookify.Application.Abstractions.Messaging;
public interface IQueryHandler<TQuery, TResponse> : IRequestHandler<TQuery, Result<TResponse>>where TQuery : IQuery<TResponse>
{
}

3. 当前时间服务接口

  • 用于提供当前时间
namespace Bookify.Application.Abstractions.Clock;public interface IDateTimeProvider
{DateTime UtcNow { get; }
}

4. 邮件发送服务接口

  • 发送邮件的服务
namespace Bookify.Application.Abstractions.Email;
public interface IEmailService
{Task SendAsync(Domain.Users.Email recipient, string subject, string body);
}

1.2 ReserveBooking Command

在这里插入图片描述

1. 处理传入的参数

  • ReserveBookingCommand.cs:返回值是Guid,参数时4个
using Bookify.Application.Abstractions.Messaging;
namespace Bookify.Application.Bookings.ReserveBooking;
public record ReserveBookingCommand(Guid ApartmentId,Guid UserId,DateOnly StartDate,DateOnly EndDate) : ICommand<Guid>;

2. ReserveBookingCommandHandler

  • 用于保存预定的处理方法
internal sealed class ReserveBookingCommandHandler : ICommandHandler<ReserveBookingCommand, Guid>
{private readonly IUserRepository _userRepository;private readonly IApartmentRepository _apartmentRepository;private readonly IBookingRepository _bookingRepository;private readonly IUnitOfWork _unitOfWork;private readonly PricingService _pricingService;private readonly IDateTimeProvider _dateTimeProvider;public ReserveBookingCommandHandler(IUserRepository userRepository,IApartmentRepository apartmentRepository,IBookingRepository bookingRepository,IUnitOfWork unitOfWork,PricingService pricingService,IDateTimeProvider dateTimeProvider){_userRepository = userRepository;_apartmentRepository = apartmentRepository;_bookingRepository = bookingRepository;_unitOfWork = unitOfWork;_pricingService = pricingService;_dateTimeProvider = dateTimeProvider;}public async Task<Result<Guid>> Handle(ReserveBookingCommand request, CancellationToken cancellationToken){// Check if the user existsUser? user = await _userRepository.GetByIdAsync(request.UserId, cancellationToken);if (user is null){return Result.Failure<Guid>(UserErrors.NotFound);}// Check if the apartment existsApartment? apartment = await _apartmentRepository.GetByIdAsync(request.ApartmentId, cancellationToken);if (apartment is null){return Result.Failure<Guid>(ApartmentErrors.NotFound);}//创建预定时间段var duration = DateRange.Create(request.StartDate, request.EndDate);// Check if the booking duration is validif (await _bookingRepository.IsOverlappingAsync(apartment, duration, cancellationToken)){return Result.Failure<Guid>(BookingErrors.Overlap);}var booking = Booking.Reserve(apartment,user.Id,duration,_dateTimeProvider.UtcNow,_pricingService);//添加booking_bookingRepository.Add(booking);//保存await _unitOfWork.SaveChangesAsync(cancellationToken);return booking.Id;}
}

3. BookingReservedDomainEvent

  • 处理 BookingReservedDomainEvent 事件的逻辑,这里只是一个处理的函数,并没有自动执行,只有当发布了事件之后,才会触发
namespace Bookify.Application.Bookings.ReserveBooking;/// 处理 BookingReservedDomainEvent 事件
internal sealed class BookingReservedDomainEventHandler : INotificationHandler<BookingReservedDomainEvent>
{private readonly IBookingRepository _bookingRepository;private readonly IUserRepository _userRepository;private readonly IEmailService _emailService;public BookingReservedDomainEventHandler(IEmailService emailService, IUserRepository userRepository, IBookingRepository bookingRepository){_emailService = emailService;_userRepository = userRepository;_bookingRepository = bookingRepository;}public async Task Handle(BookingReservedDomainEvent notification, CancellationToken cancellationToken){//通过事件里传来的 BookingId 从数据库查出预订信息。Booking? booking = await _bookingRepository.GetByIdAsync(notification.BookingId, cancellationToken);if (booking is null){return;}//根据 booking.UserId 查出用户信息。User? user = await _userRepository.GetByIdAsync(booking.UserId, cancellationToken);if (user is null){return;}//通过用户信息发送邮件。await _emailService.SendAsync(user.Email,"Booking reserved!","You have 10 minutes to confirm this booking");}
}

1.3 GetBooking Query

  • 所有查询,直接使用Dapper

1. 创建Dapper的链接接口

相关文章:

  • 8.软考高项(信息系统项目管理师)-沟通管理
  • 作为主动唤醒的节点,ECU上电如何请求通讯
  • String、StringBuilder、StringBuffer的区别
  • 翻转二叉树(简单)
  • 使用原生javascript手动实现一个可选链运算符
  • 牛客——暴力、技巧、字符与数组的使用(强强联合、字符数量)
  • 【工具】解析URL获取实际图片地址下载原始FFHQ图像
  • C++:实现线程池
  • VMware中虚拟机和主机的SSH远程连接
  • langchain使用推理模型如DeepSeek,删除回答中的推理过程<think></think>
  • 数据库实验10 函数存储
  • vitepress 复杂环境引入 mermaid
  • Python技巧:TX串口输入十六进制字符串,并获取输出,RX获取输出;循环1000次,通过分析RX输出,计算丢包率。
  • 使用docker配置Mysql
  • 深度学习:图神经网络GNN、GCN及其在推荐系统的应用
  • 人工智能 计算智能领域中分布估计算法的核心思想
  • 影刀RPA中使用AI模型
  • 【PhysUnits】1 SI Prefixes 实现解析(prefix.rs)
  • 常识补充(NVIDIA NVLink技术:打破GPU通信瓶颈的革命性互联技术)
  • 前端基础之《Vue(14)—组件通信》
  • 印巴军事对峙加剧,小规模冲突收场还是走向大战?
  • 两个灵魂,一支画笔,意大利艺术伴侣的上海灵感之旅
  • 武契奇目前健康状况稳定,短期内将暂停日常工作
  • 俄罗斯期望乌克兰在停火期间采取行动缓和局势
  • 德国斯图加特发生车辆冲撞人群事件,至少三人受伤
  • 视频丨英伟达总裁黄仁勋:美勿幻想AI领域速胜中国