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的全部内容,谢谢阅读。

最新文章

  1. signalr推送消息
  2. Search and Replace的正则表达式
  3. Sikuli增强包
  4. 兼容ie7的导航下拉菜单
  5. mysql mac启动
  6. LDAP禁止匿名访问
  7. python多线程同步
  8. 【Hibernate步步为营】--双向关联一对一映射具体解释(一)
  9. C++编程有趣的标题1 于1~9填写的运算结果的中间符号等于100
  10. Tyvj P1016 包装问题 (DP)
  11. Ant自动构建
  12. Java 字符终端上获取输入三种方式
  13. jdbc驱动的类加载过程
  14. 201621123040《Java程序设计》第4周学习总结
  15. C++格式化输出,C++输出格式控制
  16. BZOJ 1854: [Scoi2010]游戏(二分图匹配/并查集)
  17. ThinkSNS2.5前台getshell+后台任意文件删除
  18. Hexo-使用
  19. C++ 指针常量和常量指针
  20. HTTPS与证书

热门文章

  1. Adboe Flash远程代码执行_CVE-2018-4878漏洞复现
  2. chrome如何查看cookie
  3. jQuery中ajax-$.getJSON,$.getScript
  4. 10月17日 JS开始日~
  5. 导入lxml找不到etree,报ImportError:DLL load failed:找不到指定的程序
  6. 【Linux】一步一步学Linux——虚拟机简介和系统要求(04)
  7. 【翻译】Keras.NET简介 - 高级神经网络API in C#
  8. web前端css(三)
  9. 微信小程序 键盘显示短信验证码
  10. springcloud高可用方案