ASP.NET Core Clean Architecture


文章目录

  • 项目地址
  • 一、
    • [1. 重点](#1. 重点)
      • [1.1 Repository数据库接口](#1.1 Repository数据库接口)
      • [1.2 GetEventDetail 完整的Query流程](#1.2 GetEventDetail 完整的Query流程)
      • [1.3 创建CreateEventCommand并使用validation](#1.3 创建CreateEventCommand并使用validation)

项目地址

复制代码
  • 所用到的框架和插件:
复制代码

一、

1. 重点

1.1 Repository数据库接口

  • Application层的Contracts里的Persistence,存放数据库的接口
  • IAsyncRepository:基类主要功能,规定 增删改查/单一查询/分页
cs 复制代码
namespace GloboTicket.TicketManagement.Application.Contracts.Persistence
{
    public interface IAsyncRepository<T> where T : class
    {
        Task<T?> GetByIdAsync(Guid id);
        Task<IReadOnlyList<T>> ListAllAsync();
        Task<T> AddAsync(T entity);
        Task UpdateAsync(T entity);
        Task DeleteAsync(T entity);
        Task<IReadOnlyList<T>> GetPagedReponseAsync(int page, int size);
    }
}
  • ICategoryRepository.cs:添加自己独特的GetCategoriesWithEvents 方法
cs 复制代码
namespace GloboTicket.TicketManagement.Application.Contracts.Persistence
{
    public interface ICategoryRepository : IAsyncRepository<Category>
    {
        Task<List<Category>> GetCategoriesWithEvents(bool includePassedEvents);
    }
}
  • IEventRepository.cs:添加Event自己的方法
cs 复制代码
namespace GloboTicket.TicketManagement.Application.Contracts.Persistence
{
    public interface IEventRepository : IAsyncRepository<Event>
    {
        Task<bool> IsEventNameAndDateUnique(string name, DateTime eventDate);
    }
}
  • IOrderRepository.cs: 没有自己的方法,直接继承使用
cs 复制代码
namespace GloboTicket.TicketManagement.Application.Contracts.Persistence
{
    public interface IOrderRepository: IAsyncRepository<Order>
    {
        
    }
}

1.2 GetEventDetail 完整的Query流程

  • 项目层级

  • EventDetailVm.cs :用于返回给接口的数据

  • CategoryDto.cs:表示在GetEventDetail里需要用到的Dto
  • GetEventDetailQuery.cs :传入ID的值,以及返回EventDetailVm
  • GetEventDetailQueryHandler.cs :返回查询
  • 返回API的结构类似于
json 复制代码
{
    "eventId": "123e4567-e89b-12d3-a456-426614174000",
    "name": "Rock Concert",
    "price": 100,
    "artist": "The Rock Band",
    "date": "2023-12-25T20:00:00",
    "description": "An amazing rock concert to end the year!",
    "imageUrl": "https://example.com/images/rock-concert.jpg",
    "categoryId": "456e7890-f12g-34h5-i678-901234567890",
    "category": {
        "id": "456e7890-f12g-34h5-i678-901234567890",
        "name": "Music"
    }
}

1.3 创建CreateEventCommand并使用validation

  1. 设置验证类 CreateEventCommandValidator.cs
cs 复制代码
using FluentValidation;
using GloboTicket.TicketManagement.Application.Contracts.Persistence;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace GloboTicket.TicketManagement.Application.Features.Events.Commands.CreateEvent
{
    public class CreateEventCommandValidator : AbstractValidator<CreateEventCommand>
    {
        private readonly IEventRepository _eventRepository;
        public CreateEventCommandValidator(IEventRepository eventRepository)
        {
            _eventRepository = eventRepository;

            RuleFor(p => p.Name)
                .NotEmpty().WithMessage("{PropertyName} is required.")
                .NotNull()
                .MaximumLength(50).WithMessage("{PropertyName} must not exceed 50 characters.");

            RuleFor(p => p.Date)
                .NotEmpty().WithMessage("{PropertyName} is required.")
                .NotNull()
                .GreaterThan(DateTime.Now);

            RuleFor(e => e)
                .MustAsync(EventNameAndDateUnique)
                .WithMessage("An event with the same name and date already exists.");

            RuleFor(p => p.Price)
                .NotEmpty().WithMessage("{PropertyName} is required.")
                .GreaterThan(0);
        }

        private async Task<bool> EventNameAndDateUnique(CreateEventCommand e, CancellationToken token)
        {
            return !(await _eventRepository.IsEventNameAndDateUnique(e.Name, e.Date));
        }
    }
}
  1. Command类:CreateEventCommand.cs
cs 复制代码
using MediatR;

namespace GloboTicket.TicketManagement.Application.Features.Events.Commands.CreateEvent
{
    public class CreateEventCommand: IRequest<Guid>
    {
        public string Name { get; set; } = string.Empty;
        public int Price { get; set; }
        public string? Artist { get; set; }
        public DateTime Date { get; set; }
        public string? Description { get; set; }
        public string? ImageUrl { get; set; }
        public Guid CategoryId { get; set; }
        public override string ToString()
        {
            return $"Event name: {Name}; Price: {Price}; By: {Artist}; On: {Date.ToShortDateString()}; Description: {Description}";
        }
    }
}
  1. CreateEventCommandHandler.cs:处理Command,并且使用validator
  1. 自定义验证逻辑:查询在IEventRepository接口里
相关推荐
llwszx17 分钟前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
云泽野1 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person1 小时前
Java SE--方法的使用
java·开发语言·算法
小阳拱白菜2 小时前
java异常学习
java
FrankYoou3 小时前
Jenkins 与 GitLab CI/CD 的核心对比
java·docker
计算机毕设定制辅导-无忧学长4 小时前
西门子 PLC 与 Modbus 集成:S7-1500 RTU/TCP 配置指南(一)
服务器·数据库·tcp/ip
麦兜*4 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
KK溜了溜了4 小时前
JAVA-springboot 整合Redis
java·spring boot·redis
天河归来4 小时前
使用idea创建springboot单体项目
java·spring boot·intellij-idea
程序员柳4 小时前
基于微信小程序的校园二手交易平台、微信小程序校园二手商城源代码+数据库+使用说明,layui+微信小程序+Spring Boot
数据库·微信小程序·layui