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接口里
相关推荐
骑士雄师1 小时前
使用 IntelliJ IDEA 结合 DBeaver 连接 MySQL 数据库并实现数据增删查改的详细步骤:
数据库·mysql·intellij-idea
workflower3 小时前
单元测试-例子
java·开发语言·算法·django·个人开发·结对编程
YuanlongWang3 小时前
C# 基础——装箱和拆箱
java·开发语言·c#
b78gb3 小时前
电商秒杀系统设计 Java+MySQL实现高并发库存管理与订单处理
java·开发语言·mysql
wb043072014 小时前
性能优化实战:基于方法执行监控与AI调用链分析
java·人工智能·spring boot·语言模型·性能优化
天若有情6735 小时前
Java Swing 实战:从零打造经典黄金矿工游戏
java·后端·游戏·黄金矿工·swin
lichong9516 小时前
Android studio 修改包名
android·java·前端·ide·android studio·大前端·大前端++
lichong9516 小时前
Git 检出到HEAD 再修改提交commit 会消失解决方案
java·前端·git·python·github·大前端·大前端++
@yanyu6666 小时前
Tomcat安装与HTML响应实战
java·tomcat·html
呼哧呼哧.6 小时前
Spring的核心思想与注解
数据库·sql·spring