OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构( 三 )

领域根实体审计信息记录在底层实现 。开发人员不用关心审计字段的处理逻辑 。
5. 回收站式软删除采用回收站式软删除而不采用删除字段的软删除方式,是为了避免垃圾数据和多次删除造成的唯一索引问题 。自动生成和发布实体删除的领域事件,代码如上 。通过MediatR Handler,接收实体删除领域事件,将已删除的实体保存到回收站中 。
public class EntityDeletedDomainEventHandler : INotificationHandler<EntityDeletedDomainEvent>{private readonly RecycleDomainService _domainEventService;public EntityDeletedDomainEventHandler(RecycleDomainService domainEventService){_domainEventService = domainEventService;}public async Task Handle(EntityDeletedDomainEvent notification, CancellationToken cancellationToken){var eventData = JsonSerializer.Serialize(notification);RecycledEntity entity = new RecycledEntity(notification.OccurredOn, notification.OccurredBy, notification.EntityType, notification.EntityId, notification.EntityData);await _domainEventService.AddRecycledEntity(entity);}}6.CQRS(命令查询分离)通过MediatR IRequest 实现了ICommand接口和Iquery接口,业务用例请求命令或者查询继承该接口即可 。
public interface ICommand : IRequest{}public interface ICommand<out TResult> : IRequest<TResult>{}public interface IQuery<out TResult> : IRequest<TResult>{}public class AddCategoryCommand : ICommand{public AddCategoryRequest Model { get; set; }}代码中的AddCategoryCommand 增加类别命令继承ICommand 。
7.自动工作单元Commit通过MediatR 管道实现了业务Command用例完成后自动Commit,开发人员不需要手动提交 。
public class UnitOfWorkProcessor<TRequest, TResponse> : IRequestPostProcessor<TRequest, TResponse> where TRequest : IRequest<TResponse>{private readonly IUnitOfWork _unitOfWork;public UnitOfWorkProcessor(IUnitOfWork unitOfWork){_unitOfWork = unitOfWork;}public async Task Process(TRequest request, TResponse response, CancellationToken cancellationToken){if (request is ICommand || request is ICommand<TResponse>){await _unitOfWork.CommitAsync();}}}8.GRPC Message做为业务用例实体通过将GRPC proto文件放入Application项目,重用其生成的message作为业务用例实体(Model) 。
public class AddCategoryCommand : ICommand{public AddCategoryRequest Model { get; set; }}其中AddCategoryRequest 为proto生成的message 。
9.通用CURD业务用例在应用层分别实现了CURD的Command(增改删)和Query(查询) Handler 。

OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构

文章插图
OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构

文章插图
public class CUDCommandHandler<TModel, TEntity> : IRequestHandler<CUDCommand<TModel>> where TEntity : BaseEntity{private readonly CURDDomainService<TEntity> _curdDomainService;public CUDCommandHandler(CURDDomainService<TEntity> curdDomainService){_curdDomainService = curdDomainService;}public async Task<Unit> Handle(CUDCommand<TModel> request, CancellationToken cancellationToken){TEntity entity = null;if (request.Operation == "C" || request.Operation == "U"){if (request.Model == null){throw new BadRequestException($"the model of this request is null");}entity = request.Model.Adapt<TEntity>();if (entity == null){throw new ArgumentNullException($"the entity of {nameof(TEntity)} is null");}}if (request.Operation == "U" || request.Operation == "D"){if (request.Id == Guid.Empty){throw new BadRequestException($"the Id of this request is null");}}switch (request.Operation){case "C":await _curdDomainService.Create(entity);break;case "U":await _curdDomainService.Update(entity);break;case "D":await _curdDomainService.Delete(request.Id);break;}return Unit.Value;}}

经验总结扩展阅读