demo地址:ABP.WindowsService

该文章是系列文章 基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业 的其中一篇。

AutoMapper简介

AutoMapper是一个简单的小型的对象映射库,是为了解决一个繁杂的问题 - 将一个对象映射到另一个对象的到处乱飞的胶水代码。这类胶水代码非常沉闷,让人怀疑自己的工作的价值性。AutoMapper就是你摆脱此类代码的福音。

官网地址:https://automapper.org/

GitHub地址:https://github.com/AutoMapper/AutoMapper

AutoMapper的简单使用

这里拿官网的例子做一个简单说明,主要是为了引出在Abp中是如何使用的,来进行对比。使用AutoMapper将遇到的最经典的两个场景。

  1. 最多遇到的场景,应该是接口返回的DTO和数据库Entity,出于敏感信息保护或者减少接口返回数据等等的原因,DTO返回的属性或者字段有所删减,也就是说需要映射的属性或者字段属性名称一致。
  2. DTO和Entity名称不一致,甚至类型不同,相互转换时甚至需要对数据有处理。

下面的例子就是字段属性基本一致。

public class Order
{
public string OrderName { get;set; }
public string PhoneNumber { get;set; }
}
public class OrderDto
{
public string OrderName { get;set; }
}
var config = new MapperConfiguration(cfg => cfg.CreateMap<Order, OrderDto>());
var mapper = config.CreateMapper();
OrderDto dto = mapper.Map<OrderDto>(order);

或者

var config = new MapperConfiguration(cfg => cfg.CreateMap<Order, OrderDto>());
var mapper = new Mapper(config);
OrderDto dto = mapper.Map<OrderDto>(order);

Abp.AutoMapper的简单使用

Abp.AutoMapper的官网文档:https://aspnetboilerplate.com/Pages/Documents/Object-To-Object-Mapping

Abp.AutoMapper的Nuget地址:https://www.nuget.org/packages/Abp.AutoMapper

添加nuget包

Install-Package Abp.AutoMapper

添加AbpAutoMapperModule模块

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyJobCoreModule : AbpModule
{
}

指定映射关系

自动映射

你可以通过属性AutoMap, AutoMapFrom, AutoMapTo指定映射关系

改造上面的之前的例子

[AutoMapFrom(typeof(Order))]
public class OrderDto
{
public string OrderName { get;set; }
}

或者

[AutoMapTo(typeof(OrderDto))]
public class Order
{
public string OrderName { get;set; }
public string PhoneNumber { get;set; }
}

但是属性的使用场景比较窄,稍微复杂一点的场景就无法满足,比如,指定忽略一些字段,或者字段名称不同需要显示指定。

自定义映射

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyJobCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
{
config.CreateMap<Order, OrderDto>();
});
}
}

忽略字段

config.CreateMap<Order, OrderDto>()
.ForMember(u => u.PhoneNumber, options => options.Ignore());

字段名不一致

OrderDto增加手机号字段Tel,映射Order字段PhoneNumber

    public class OrderDto
{
public string OrderName { get; set; }
public string Tel { get; set; }
}
config.CreateMap<Order, OrderDto>()
.ForMember(u => u.Tel, options => options.MapFrom(input => input.PhoneNumber));

需要对字段进行处理后返回

比如,隐藏11位手机号的中间4位

private static string HideTel(string input)
{
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
var outReplace = Regex.Replace(input, "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
return outReplace;
}
config.CreateMap<Order, OrderDto>()
.ForMember(u => u.Tel, options => options.MapFrom(input => HideTel(input.PhoneNumber)));

拼接映射

又比如OrderDto新增邮寄地址和收货地址

namespace Demo.MyJob.Entity.Dto
{
public class OrderDto
{
public string OrderName { get; set; }
public string Tel { get; set; }
public string PostalAddress { get; set; }
public string DeliveryAddress { get; set; }
}
}

Order的相关表OrderAddress类型定义

namespace Demo.MyJob.Entity
{
public class OrderAddress
{
public string OrderId { get; set; }
public string PostalAddress { get; set; }
public string DeliveryAddress { get; set; }
}
}

这时就需要OrderAddress和Order的数据相结合映射OrderDto,怎么实现呢?借助元组Tuple。

config.CreateMap<(Order, OrderAddress), OrderDto>()
.ForMember(u => u.Tel, options => options.MapFrom(input => HideTel(input.Item1.PhoneNumber)))
.ForMember(u => u.OrderName, options => options.MapFrom(input => input.Item1.OrderName))
.ForMember(u => u.PostalAddress, options => options.MapFrom(input => input.Item2.PostalAddress))
.ForMember(u => u.DeliveryAddress, options => options.MapFrom(input => input.Item2.DeliveryAddress))
;

精简配置

需要自定义的映射关系过多时,会使得PreInitialize变大,不便于管理和查看。

public override void PreInitialize()
{
Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
{
config.CreateMap<(Order, OrderAddress), OrderDto>()
.ForMember(u => u.Tel, options => options.MapFrom(input => HideTel(input.Item1.PhoneNumber)))
.ForMember(u => u.OrderName, options => options.MapFrom(input => input.Item1.OrderName))
.ForMember(u => u.PostalAddress, options => options.MapFrom(input => input.Item2.PostalAddress))
.ForMember(u => u.DeliveryAddress, options => options.MapFrom(input => input.Item2.DeliveryAddress))
;
});
}

如何精简?新增类型MyMapperProfile,继承AutoMapper.Profile

using System.Text.RegularExpressions;
using AutoMapper;
using Demo.MyJob.Entity;
using Demo.MyJob.Entity.Dto; namespace Demo.MyJob.MapperProfiles
{
class MyMapperProfile : Profile
{
private static string HideTel(string input)
{
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
var outReplace = Regex.Replace(input, "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
return outReplace;
}
public MyMapperProfile()
{
CreateMap<Order, OrderDto>()
.ForMember(u => u.Tel, options => options.MapFrom(input => HideTel(input.PhoneNumber))); CreateMap<(Order, OrderAddress), OrderDto>()
.ForMember(u => u.Tel, options => options.MapFrom(input => HideTel(input.Item1.PhoneNumber)))
.ForMember(u => u.OrderName, options => options.MapFrom(input => input.Item1.OrderName))
.ForMember(u => u.PostalAddress, options => options.MapFrom(input => input.Item2.PostalAddress))
.ForMember(u => u.DeliveryAddress, options => options.MapFrom(input => input.Item2.DeliveryAddress))
;
}
}
}

修改PreInitialize

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyJobCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
{
config.AddMaps(typeof(MyJobCoreModule));
});
}
}

Abp.AutoMapper版本低于4.8.0的可以修改为

config.AddProfiles(typeof(MyJobCoreModule));

以上就是如何在Abp框架下灵活使用AutoMapper的全部内容,谢谢阅读。

在ABP中灵活使用AutoMapper的更多相关文章

  1. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

  2. ABP源码分析三十五:ABP中动态WebAPI原理解析

    动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...

  3. ABP源码分析四十七:ABP中的异常处理

    ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...

  4. ABP中使用Redis Cache(1)

    本文将讲解如何在ABP中使用Redis Cache以及使用过程中遇到的各种问题.下面就直接讲解使用步骤,Redis环境的搭建请直接网上搜索. 使用步骤: 一.ABP环境搭建 到http://www.a ...

  5. ABP中使用Redis Cache(2)

    上一篇讲解了如何在ABP中使用Redis Cache,虽然能够正常的访问Redis,但是Redis里的信息无法同步更新.本文将讲解如何实现Redis Cache与实体同步更新.要实现数据的同步更新,我 ...

  6. ABP中使用OAuth2(Resource Owner Password Credentials Grant模式)

    ABP目前的认证方式有两种,一种是基于Cookie的登录认证,一种是基于token的登录认证.使用Cookie的认证方式一般在PC端用得比较多,使用token的认证方式一般在移动端用得比较多.ABP自 ...

  7. 在Abp中集成Swagger UI功能

    在Abp中集成Swagger UI功能 1.安装Swashbuckle.Core包 通过NuGet将Swashbuckle.Core包安装到WebApi项目(或Web项目)中. 2.为WebApi方法 ...

  8. 记载abp中Dbcontext的疑问

    q:abp中httpcontext如何在一次请求中保证获取的是相同的实例. 大牛的原话: LifestylePerWebRequest does not works good with async. ...

  9. ABP中动态WebAPI原理解析

    ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类 ...

随机推荐

  1. Ajax出现error常见情况(详细版)-火狐浏览器(Firefox)兼容性问题

    作为一个程序员,遇到兼容性问题真的很苦恼,尤其是对我这种前端小菜鸡来说遇到了甚是凄惨.一般来说兼容性问题出现率Chrome < IE < Firefox  (╯°Д°)╯︵┴┴ . 言归正 ...

  2. 如何正确选择挑选适合的VPS服务器

    就来讲讲,如何挑选适合你的VPS.基本过程就是:1.你使用VPS的用途:2.你需要的线路:3.你要选择的操作系统:4.你购买VPS的大概预算是多少. 一.用途方法,其实买VPS就是:建站.VPN使用. ...

  3. resolv.conf 的超时(timeout)与重试(attempts)机制

    /etc/resolv.conf 有两个默认的值至关重要,一个是超时的 timeout,一个是重试的 attempts,默认情况下,前者是 5s 后者是 2 次.这个估计很多工程师都不是很在意,一般情 ...

  4. Python程序中的协程操作-gevent模块

    目录 一.安装 二.Gevent模块介绍 2.1 用法介绍 2.2 例:遇到io主动切换 2.3 查看threading.current_thread().getName() 三.Gevent之同步与 ...

  5. 关于C51 keil使用中.c文件的链接心得

    这个问题一直烦了我很久,使用C51 keil进行.c文件链接的时候,老是报错诸如下面的信息: *** ERROR L104: MULTIPLE PUBLIC DEFINITIONS SYMBOL: a ...

  6. idea创建springcloud主工程和springboot子项目

    创建主工程,选择file-new-project,选择maven,直接next 填写GroupId包名,ArtifactId项目名,next-finish 创建子项目springboot,项目右击-n ...

  7. HDU 4819:Mosaic(线段树套线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给出一个矩阵,然后q个询问,每个询问有a,b,c,代表(a,b)这个点上下左右c/2的矩形区域内的( ...

  8. Codeforces 758A:Holiday Of Equality(水题)

    http://codeforces.com/problemset/problem/758/A 题意:给出n个值,求这里面每个值都要变成最大的那个数,总共需要加上多少. 思路:找出最大的直接算. #in ...

  9. 跟我学SpringCloud | 第十三篇:Spring Cloud Gateway服务化和过滤器

    SpringCloud系列教程 | 第十三篇:Spring Cloud Gateway服务化和过滤器 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich. ...

  10. CentOS 6.5 下安装及使用中文输入法

    第一次在本机环境下搭载Linux环境,但搭载后发现在CentOS 6.5只能英文输入,于是试着安装并启用中文输入法,经过一翻折腾,实现了在终端和自带火狐浏览器下支持中文输入法. CentOS下安装中文 ...