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 。

文章插图

文章插图
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;}}开发人员只需要在GRPC层简单调用即可实现CURD业务 。
public async override Task<AddProductReply> AddProduct(AddProductRequest request, ServerCallContext context){CUDCommand<AddProductRequest> addProductCommand = new CUDCommand<AddProductRequest>();addProductCommand.Id = Guid.NewGuid();addProductCommand.Model = request;addProductCommand.Operation = "C";await _mediator.Send(addProductCommand);return new AddProductReply(){Message = "Add Product sucess"};}10. 业务实体验证通过FluentValidation和MediatR 管道实现业务实体自动验证,并自动抛出自定义异常 。

文章插图

文章插图
public class RequestValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>{private readonly IEnumerable<IValidator<TRequest>> _validators;public RequestValidationBehavior(IEnumerable<IValidator<TRequest>> validators){_validators = validators;}public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next){var errors = _validators.Select(v => v.Validate(request)).SelectMany(result => result.Errors).Where(error => error != null).ToList();if (errors.Any()){var errorBuilder = new StringBuilder();errorBuilder.AppendLine("Invalid Request, reason: ");foreach (var error in errors){errorBuilder.AppendLine(error.ErrorMessage);}throw new InvalidRequestException(errorBuilder.ToString(), null);}return await next();}}开发人员只需要定义验证规则即可
public class AddCategoryCommandValidator : AbstractValidator<AddCategoryCommand>{public AddCategoryCommandValidator(){RuleFor(x => x.Model.CategoryName).NotEmpty().WithMessage(p => "类别名称不能为空.");}}11.请求日志和性能日志记录基于MediatR 管道实现请求日志和性能日志记录 。
推荐阅读
- 我的 Kafka 旅程 - Consumer
- 最早人工呼吸救人的医学家是谁 最早采用人工呼吸的医学家是谁
- 宝马gtsuv是什么意思
- 电磁炉插电没开有辐射吗?
- 转炉煤气回收一般采用什么方法
- 合理安排工作时间,提高工作效率 采用工作时间记录法提高工作效率
- 贴梗海棠怎样繁殖,一般采用分株繁殖、压条繁殖、插扦繁殖
- 羽衣甘蓝栽培要点
- 名爵是国产还是合资车品牌 名爵是国产还是合资车?
- 品胜易充如何输出2a