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. PTA实验4-2-3 验证“哥德巴赫猜想” (20分)

    实验4-2-3 验证"哥德巴赫猜想" (20分) 数学领域著名的"哥德巴赫猜想"的大致意思是:任何一个大于2的偶数总能表示为两个素数之和.比如:24=5+19, ...

  2. Spark解决SQL和RDDjoin结果不一致问题(工作实录)

    问题描述:DataFrame的join结果不正确,dataframeA(6000无重复条数据) join dataframeB(220条无重复数据,由dataframeA转化而来,key值均源于dat ...

  3. JDBC:(java database Connection) java数据库连接。

    JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC连接步骤: 1.先导入jar包,把jar放入到工程下并 ...

  4. MySQL:提高笔记-2

    MySQL:提高笔记-2 学完基础的语法后,进一步对 MySQL 进行学习,第一篇为:MySQL:提高笔记-1,这是第二篇内容 说明:这是根据 bilibili 上 黑马程序员 的课程 mysql入门 ...

  5. [no code][scrum meeting] Beta 10

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月25日15:00,主持者:伦泽标 下次例会时间:5月26日11:30,主持者: 一.工作汇报 ...

  6. Unity 制作不规则形状button

    在游戏开发中,我们有时需要制作不规则形状的按键. Unity3d中使用UGUI的Button控件只能实现规则的长方形按钮.而通过给Button的Image组件添加对应的贴图(sprite)我们可以实现 ...

  7. springboot整合rabbitmq实现生产者消息确认、死信交换器、未路由到队列的消息

    在上篇文章  springboot 整合 rabbitmq 中,我们实现了springboot 和rabbitmq的简单整合,这篇文章主要是对上篇文章功能的增强,主要完成如下功能. 需求: 生产者在启 ...

  8. 查找最小生成树:克鲁斯克尔算法(Kruskal)算法

    一.算法介绍 Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表.用来解决同样问题的还有Prim算法和Boruvka算法等.三种算法都是贪心算法的应用.和 ...

  9. Java设计模式——模板设计模式

    模板设计模式 1.模板模式简介 模板模式(Template ):模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑 ...

  10. NavigationView使用简介

    Android支持直接创建带有NavigationView的Activity,这里主要介绍NavigationView的逻辑. NavigationView通常是跟DrawerLayout一起使用.D ...