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. NOIP模拟79

    T1 F 解题思路 因为每个点会产生贡献当且仅当它在可以到他的点之前被删除,并且此题遵守期望的线性性. 因此设所有可以到达点 \(i\) 的数量为 \(c_i\) 那么答案就是 \(\sum \fra ...

  2. GAN实战笔记——第二章自编码器生成模型入门

    自编码器生成模型入门 之所以讲解本章内容,原因有三. 生成模型对大多数人来说是一个全新的领域.大多数人一开始接触到的往往都是机器学习中的分类任务--也许因为它们更为直观:而生成模型试图生成看起来很逼真 ...

  3. C++/CLR 使用(VS2012,VS2013,VS2015)编写

    转载自:http://www.th7.cn/system/win/201509/129417.shtml VS2010以及以前的版本,创建项目时都可以在CLR下找到"Windows窗体应用程 ...

  4. NX9.0和NX10.0做自定义操作可以用的函数

    NX9.0:LIBUFUNX.DLL int UF_OPER_ask_check_geom(void *,int *,unsigned int * *) int UF_OPER_ask_first_o ...

  5. Linux中使用dd制作文件的.img

    dd if=/dev/zero of=new_img.img bs=1M count=20   //生成20M的文件,bs块的大小,count块的数量 mkfs.ext3 new_img.img  / ...

  6. Linux信号处理编程

    01. 学习目标 了解信号中的基本概念 熟练使用信号相关的函数 了解内核中的阻塞信号集和未决信号集作用 熟悉信号集操作相关函数 熟练使用信号捕捉函数signal 熟练使用信号捕捉函数sigaction ...

  7. Java字符串分割函数split源码分析

    spilt方法作用 以所有匹配regex的子串为分隔符,将input划分为多个子串. 例如: The input "boo:and:foo", for example, yield ...

  8. 优客源创会 西安站 西邮Linux兴趣小组

    2016年5月19日晚7:00,优客源创会西安站在西安邮电大学长安校区东区教学楼FF305如期举行,西安邮电大学计算机学院教授.西邮Linux兴趣小组指导老师陈莉君.王小银老师和来自开源中国的周凯先生 ...

  9. css 按钮悬停效霓虹灯特效

    css 按钮悬停效霓虹灯特效 <!DOCTYPE html> <html lang="en"> <head> <meta charset=

  10. go输入Hello word

    package main import "fmt" func main() {     fmt.Println("hello word") } 输入hello ...