文章目录
- 项目地址
- 一、DTO
- 1.1 创建Restaurant的Dto
- 1.2 修改之前未使用Dto的接口
- 1.2.1 修改GetRestaurantByIdUseCase
- 1.2.2 修改IGetRestaurantByIdUseCase接口
- 1.2.3 再次请求接口
- 1.3 显示Dish List
- 1.3.1创建DishDto
- 1.3.2 在RestaurantDto里添加DishDto
- 1.3.3 使用Include添加Dishes
- 1.4 使用AutoMapper 简化Dto的过程
- 1.4.1 添加
- 1.4.2 删除
- 1.4.3 修改
- 1.4.4
- 二、CRUD完善
- 2.1 Create Restaurants
- 2.1.1 创建Create的Dto
- 2.1.2 修改AutoMapper的RestaurantsProfile
- 2.1.3 添加Create的UseCase
- 2.1.4 提取UseCase为接口
- 2.1.5 添加Create方法到接接口
- 2.1.6 实现接口IRestaurantsRepository
- 2.1.7 创建Create的Controller
- 2.1.8测试接口
- 三、CQRS 模式
- 3.1安装MediaR包
- 3.2 Create Restaurant 添加餐厅
- 1. 创建Command命令
- 2. 创建Handler
- 3.3 读取所有餐厅和一个餐厅
- 3.3.1 获取所有餐厅
- 1. GetAllRestaurantsQuery
- 2. GetAllRestaurantsQueryHandler
- 3.3.2 根据Id获取一个餐厅
- 1. GetRestaurantByIdQuery
- 2. GetRestaurantByIdQueryHandler
- 3.4 在ServiceCollectionExtensions注册服务
- 3.5 controller里修改方式
项目地址
- 教程作者:Jakub Kozera
- 教程地址UD:
https://www.csdn.com/course/aspnet-core-web-api-clean-architecture-azure/learn/lecture/42032838#overview
- 代码仓库地址:
- 所用到的框架和插件:
.net 8
一、DTO
避免直接暴露数据库实体
1.1 创建Restaurant的Dto
- 在Restaurants.Application创建
Dtos文件夹
; - 创建
RestaurantDto.cs
,FromRestaurant静态方法,只是为了包装真正的实体类只返回需要的属性;
using Restaurants.Domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Restaurants.Application.Dtos
{public class RestaurantDto{public int Id { get; set; }public string Name { get; set; } = default!;public string Description { get; set; } = default!;public string Category { get; set; } = default!;public bool HasDelivery { get; set; }public string? City { get; set; }public string? Street { get; set; }public string? ZipCode { get; set; }public List<DishDto> Dishes { get; set; } = new List<DishDto>();public static RestaurantDto FromRestaurant(Restaurant restaurant){return new RestaurantDto(){Id = restaurant.Id,Name = restaurant.Name,Description = restaurant.Description,Category = restaurant.Category,HasDelivery = restaurant.HasDelivery,City = restaurant.Address?.City,Street = restaurant.Address?.Street,ZipCode = restaurant.Address?.ZipCode,};}}
}
1.2 修改之前未使用Dto的接口
- 只需要在Application层进行修改
1.2.1 修改GetRestaurantByIdUseCase
- 调用
RestaurantDto
的静态方法FromRestaurant
,并传入实体类restaurant
,进行包装,只返回包装后的类;
1.2.2 修改IGetRestaurantByIdUseCase接口
- 只需要修改IGetRestaurantByIdUseCase的接口;
using Restaurants.Application.Dtos;namespace Restaurants.Application.RestaurantsUseCase
{public interface IGetAllRestaurantsUseCase{Task<IEnumerable<RestaurantDto>> Execute();}
}
1.2.3 再次请求接口
- 我们需要隐藏的Email和Phone的信息,已经没有显示了
- 但是有个问题是,dishes的列表是空的
1.3 显示Dish List
1.3.1创建DishDto
- 在
Dtos文件夹
下,创建DishDto.cs
,其中,静态方法的FromEntity(Dish dish)
用于转换Dish为DishDto
using Restaurants.Domain.Models;namespace Restaurants.Application.Dtos
{public class DishDto{public int Id { get; set; }public string Name { get; set; } = default!;public string Description { get; set; } = default!;public decimal Price { get; set; }public int? Kilocalories { get; set; }public static DishDto FromEntity(Dish dish){return new DishDto(){Id = dish.Id,Name = dish.Name,Description = dish.Description,Price = dish.Price,Kilocalories = dish.Kilocalories};}}
}
1.3.2 在RestaurantDto里添加DishDto
- 将restaurant.Dishes 转为DishDto是关键,使用
Select
1.3.3 使用Include添加Dishes
- 在EF执行的地方,添加把Dishes添加进入;
Restaurants.Infrastructure
层的Repositories
RestaurantsRepository.cs
1.4 使用AutoMapper 简化Dto的过程
- 上面我们都是通过自己创建静态方法来手动创建和注入Dto,使用AutoMapper可以自动
1.4.1 添加
- 在Dtos文件夹下,添加
DishesProfile.cs
和RestaurantsProfile.cs
1.4.2 删除
- 删除之前自己添加的静态方法
1.4.3 修改
- 修改之前UseCase里的获取Dto的方法,改为automapper
1.4.4
- 在Application的Extensions里注册服务
二、CRUD完善
2.1 Create Restaurants
2.1.1 创建Create的Dto
- 由于Create需要餐厅的详细地址和电话,所以之前读取餐厅的DTO无法使用
using Restaurants.Domain.Models;namespace Restaurants.Application.Dtos
{public class CreateRestaurantDto{public int Id { get; set; }public string Name { get; set; } = default!;public string Description