文章目录
- 项目地址
- 一、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. 映射规则
- 2. 使用映射
- 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可以自动;
Dto转为Model需要映射,Model转为Dto也需要映射;
如果Dto和Model的字段不一样,就要配置映射规则
1.4.1 添加
- 在Dtos文件夹下,添加
DishesProfile.cs
和RestaurantsProfile.cs
,文件里存放的是映射规则
1. 映射规则
2. 使用映射
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; } = defa