AutoMapper 可以很方便完成数据对象之间的转换。

Dto -> Entity

Entity -> ViewModel

Step 1:通过 NuGet 安装 AutoMapper 的包。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="9.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
</ItemGroup> </Project>

Project.csproj

准备两个类 User 和 Department

    public class User
{
public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Remark { get; set; } public int DepartmentId { get; set; } public Department DepartmentInfo { get; set; }
}

User

    public class Department
{
public int Id { get; set; } public string Name { get; set; } public string Remark { get; set; }
}

Department

创建 User 的 Dto 和 ViewModel

    public class UserDto
{
public int Id { get; set; } public string Name { get; set; }
}

UserDto

    public class UserViewModel
{
public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Remark { get; set; } public int DepartmentId { get; set; } public string DepartmentName { get; set; }
}

UserViewModel

Step 2:配置好对象之间的转换。

创建类 UserMapper 继承抽象类 Profile

    public class UserMapper : Profile
{
public UserMapper()
{
CreateMap<UserDto, User>();
CreateMap<User, UserViewModel>()
.BeforeMap((u, v) => u.Remark = "Good")
.ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId))
.ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name))
.AfterMap((u, v) => u.Age++);
}
}

UserMapper

Profile 里面实现了两个接口

Step 3:注册服务

在 Startup.cs 的 ConfigureServices 方法中注册。

        public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAutoMapper(typeof(UserMapper));
// ...
}

ConfigureServices

Step 4:使用

创建 api 控制器

声明 private readonly IMapper _mapper;

    [Route("api/[controller]/[action]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IMapper _mapper; public UserController(IMapper mapper)
{
_mapper = mapper;
} [ActionName("dto")]
[HttpGet]
public IActionResult DtoToEntity()
{
var userDto = new UserDto() { Id = 1, Name = "Bill" };
var userEntity = _mapper.Map<UserDto, User>(userDto); JsonResult result = new JsonResult(userEntity);
return result;
} [ActionName("vo")]
[HttpGet]
public IActionResult EntityToViewModel()
{
var department = new Department() { Id = 101, Name = "Market" };
var user = new User() { Id = 1, Name = "Bill", Age = 25, DepartmentId = 101, DepartmentInfo = department };
var viewModel = _mapper.Map<User, UserViewModel>(user); JsonResult result = new JsonResult(viewModel);
return result;
} }

UserController

结果:

Dto -> Entity

Entity -> ViewModel

Step 5:自动化注册

如果每添加一个 Mapper 都需要修改 StartUp 类来完成注册,不是什么好方式。

自动化注册才是更好的(主要还是方便摸鱼)。

为了实现自动化注册,需要找到项目中的所有 Mapper 对象,要给 Mapper 打上一个标记。

添加接口类 IProfile

    public interface IProfile
{ }

IProfile

在所有的 Mapper 类里面,实现这个接口。

    public class UserMapper : Profile, IProfile
{
public UserMapper()
{
CreateMap<UserDto, User>();
CreateMap<User, UserViewModel>()
.BeforeMap((u, v) => u.Remark = "Good")
.ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId))
.ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name))
.AfterMap((u, v) => u.Age++);
}
}

UserMapper

再通过查找所有实现了 IProfile 接口的类,就可以找到所有的 Mapper 对象。

( Profile 是 AutoMapper 组件里的接口,必须自定义项目中的唯一标记。)

创建 MapperRegister 类,实现获取所有的 Mapper 对象。

    public class MapperRegister
{
/// <summary>
/// 通过反射自动化注册
/// </summary>
/// <returns></returns>
public static Type[] MapType()
{ Assembly ass = Assembly.GetAssembly(typeof(IProfile));
Type[] types = ass.GetTypes(); List<Type> allList = new List<Type>(); foreach (Type item in types)
{
if (item.IsInterface) continue;//判断是否是接口
Type[] ins = item.GetInterfaces();
foreach (Type ty in ins)
{
if (ty == typeof(IProfile))
{
allList.Add(item);
}
}
} Type[] alltypes = allList.ToArray();
return alltypes;
} }

MapperRegister

修改 StrartUp 类,调整注册方式。

        public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(); //services.AddAutoMapper(typeof(UserMapper));
//自动化注册
services.AddAutoMapper(MapperRegister.MapType()); }

Startup

这样就可以每次添加 Mapper 类的时候,只需要添加 IProfile 标记,就可以自动注册了。

自动化注册方式二

在很多常见的项目中,同一个项目的Mapper文件都是放在同一个文件夹内。命名都以 Mapper 结尾。

然后在 Startup.cs 里面

            services.AddAutoMapper(
Assembly.Load("Leaf.Application").GetTypes()
.Where(t => t.FullName.EndsWith("Mapper"))
.ToArray()
);
Assembly.Load() 里面传的是当前项目的名称,或者类库的名称。获取当前项目下的所有类文件。
通过 Lamda 表达式 Where 找到所有以 Mapper 结尾的文件。
这样就可以自动注册项目内的所有 Mapper 文件了。
 
摸鱼又更进了一步。
 
AutoMapper 配合强类型字段的 ORM 特别好用。比如 EF 。
入参控制好 Add 的 Dto。
返回参数 控制好 ViewModel。
这些文件都可以从数据库 Entity 对象里面复制,不需要手写字段。
无论多长的字段,都可以通过 Ctrl + C 和 Ctrl + V 来创建对应的 Dto 和 ViewModel 。
再通过 AutoMapper 的转换。
做 CURD 接口的时候,不需要写任何 Entity 里已存在的字段。
然后就可以愉快地上班摸鱼了。

.net core 3.1 WebAPi 使用 AutoMapper 9.0、10.0的更多相关文章

  1. 分享一个简单程序(webApi+castle+Automapper+Ef+angular)

    前段时间在周末给朋友做了一个小程序,用来记录他们单位的一些调度信息(免费,无版权问题).把代码分享出来.整个程序没有做任何架构.但是麻雀虽小,用到的技术也没少.WebApi+Castle+AutoMa ...

  2. asp.net core系列 38 WebAPI 返回类型与响应格式--必备

    一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...

  3. ASP.NET Core 2.2 WebApi 系列【九】使用SignalR (作者:tenghao510 ) 学习及内容补充

    原文地址:  ASP.NET Core 2.2 WebApi 系列[九]使用SignalR 今天,看到了大牛的这篇博文,  发了一下评论, 我很惊喜, 没想到他很快就回复了我,  而且通过QQ帮助了S ...

  4. 【Docker】 .Net Core 3.1 webapi 集成EF Code First,使用MySql进行业务操作 、配置swagger (三)

    系列目录: [Docker] CentOS7 安装 Docker 及其使用方法 ( 一 ) [Docker] 使用Docker 在阿里云 Centos7 部署 MySQL 和 Redis (二) [D ...

  5. [转]Could not load file or assembly 'System.Core, Version=2.0.5.0 和autofac冲突的问题

    Could not load file or assembly 'System.Core, Version=2.0.5.0 和autofac冲突的问题 来源:http://www.cnblogs.co ...

  6. Could not load file or assembly 'System.Core, Version=2.0.5.0 和autofac冲突的问题

    在部署到iis的时候会出现这个状况. 解决:下载安装这个补丁 http://support.microsoft.com/kb/2468871 http://www.microsoft.com/zh-c ...

  7. 使用Autofac部署IIS6.0时未能加载文件或程序集“System.Core, Version=2.0.5.0...“

    错误信息 .net4.0项目中使用autofac这个IOC容器,在部署在win2003+iis6时出现以下错误. “/”应用程序中的服务器错误. --------------------------- ...

  8. NET Core 拓展方法和中间件集合(支持NET Core2.0+)

    # Pure.NETCoreExtentensions https://github.com/purestackorg/Pure.NETCoreExtensions NET Core 拓展方法和中间件 ...

  9. System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes”

    “System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes” 或 ...

随机推荐

  1. 【UE4 C++】编程子系统 Subsystem

    概述 定义 Subsystems 是一套可以定义.自动实例化和释放的类的框架.可以将其理解为 GamePlay 级别的 Component 不支持网络赋值 4.22开始引入,4.24完善.(可以移植源 ...

  2. 如何使用远程工具连接Linux服务器

    大家好,今天我想和大家分享一下Linux如何连接远程控制工具我们都知道,Linux是著名的开源服务器操作系统,而在运维工程师的实际工作当中,我们不大可能时时刻刻都在服务器本地操作.因此这时,我们要用远 ...

  3. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. Java:Iterator接口与fail-fast小记

    Java:Iterator接口与fail-fast小记 对 Java 中的 Iterator接口 和 fail-fast,做一个微不足道的小小小小记 Iterator Iterator接口 Itera ...

  5. Spring Cloud Gateway Route Predicate Factory 的使用

    Spring Cloud Gateway的使用 一.需求 二.基本组成 1.简介 2.核型概念 1.Route 路由 2.Predicate 谓语.断言 3.Filter 过滤器 3.工作原理 三.网 ...

  6. netty中使用protobuf实现多协议的消息

    在我们使用 netty 的过程中,有时候为了高效的传输数据,经常使用 protobuf 进行数据的传输,netty默认情况下为我们实现的 protobuf 的编解码,但是默认的只能实现单个对象的编解码 ...

  7. 8.18考试总结[NOIP模拟43]

    又挂了$80$ 好气哦,但要保持优雅.(草 T1 地衣体 小小的贪心:每次肯定从深度较小的点向深度较大的点转移更优. 模拟一下,把边按链接点的子树最大深度排序,发现实际上只有上一个遍历到的点是对当前考 ...

  8. 集合先从ArrayList开始

    本篇文章非常建议直接从经典Demo开始哦~ 一.ArrayList简介 ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序 ...

  9. 『学了就忘』Linux基础 — 5、使用VMware创建虚拟机

    目录 1.在VMware中创建虚拟机 (1)点击[创建新的虚拟机]. (2)选择系统安装方式 (3)选择客户机操作系统 (4)自定义虚拟机的名称和安装位置. (5)指定系统硬盘容量 (6)完成创建 2 ...

  10. 洛谷 P6075 [JSOI2015]子集选取

    链接:P6075 前言: 虽然其他大佬们的走分界线的方法比我巧妙多了,但还是提供一种思路. 题意: %&¥--@#直接看题面理解罢. 分析过程: 看到这样的题面我脑里第一反应就是DP,但是看到 ...