阅读目录

  1. 介绍

  2. 基本使用

  3. 自动分割映射(Flattening)

  4. 自定义字段映射(Projection)

  5. 验证配置(Configuration validation)

介绍

AutoMapper是一个轻量级的类库,主要功能是把一个对象转换成另外一个对象,而避免我们每次都手工去转换。

常见几种使用场景:

  • 对外服务接口,把逻辑层的实体转换成服务消费者需要的字段。

  • UI展现层,把业务对象转换成UI需要展现的字段。

  • 用户的输入输出,把DTO与领域模型互转。

AutoMapper支持的平台:

  • .NET 4+
  • Silverlight 5
  • Windows Phone 8+
  • .NET for Windows Store apps (WinRT)
  • Windows Universal Apps
  • Xamarin.iOS
  • Xamarin.Android

基本使用

NuGet安装使用

PM> install-package automapper

注册2个类型之间的映射关系:

Mapper.CreateMap<Order, OrderDto>();

通过Map方法生成目标类型新对象,OrderDto是目标类型,order是源对象。

OrderDto dto = Mapper.Map<OrderDto>(order);

AutoMapper默认是根据属性名称自动与源进行规则匹配,赋值。
例:FirstName=FirstName,FirstName=firstname,mapper不区分大小写。

配置

使用静态全局mapper注册的话,应该放在应用程序启动的时候。
比如ASP.NET的Global.asax文件中Application_Start()方法。

测试

AutoMapper提供下面方法去验证我们的配置是否有效,无效会抛出异常:

Mapper.AssertConfigurationIsValid();

自动分割映射(Flattening)

实际中我们经常需要把一个复杂对象映射一个简单对象,给UI使用,例:

public class Order
{
public Customer Customer { get; set; }
public decimal GetTotal()
{
return *;
}
}
public class Customer
{
public string Name { get; set; }
}

然后匹配Order对象到一个简单的OrderDto,仅包含我们需要的字段:

public class OrderDto
{
public string CustomerName { get; set; }
public decimal Total { get; set; }
}

当我们使用AutoMapper创建Order/OrderDto映射配置时,AutoMapper映射器会尝试在Order中,寻找名称匹配的成员,有3种匹配方式。

  • 名称相同的属性进行映射,不区分大小写。
  • 带Get前缀的方法进行映射,如例子中:
    映射器会把Order中的GetTotal分割成Get、Total 2个词, 把分割出来的Total与OrderDto中的Order进行匹配映射。
  • 目标类型属性分割,如例子中:
    映射器会把OrderDto中的CustomerName分割成Customer、Name。然后在Order中去Customer类属性中查找Name的属性。

内部匹配根据帕斯卡拼写法(PascalCase)。

自定义字段映射(Projection)

自动分割映射能预判源对象到目标对象的匹配,但不能自定义配置映射。AutoMapper在构造目标对象时,会自动按照规则进行目标与源属性分割匹配。
所以自动分割映射虽然方便智能,但却不是那么精确可控制的。 在很多场景下,我们更需要的是把A属性拆分映射B、C 2个属性上,或单独映射D属性上。
AutoMapper提供一种自定义成员映射的方法。例如:

public class CalendarEvent
{
public DateTime Date { get; set; }
public string Title { get; set; }
}

我们想在web页面上输出更多的字段:

public class CalendarEventForm
{
public DateTime EventDate { get; set; }
public int EventHour { get; set; }
public int EventMinute { get; set; }
public string Title { get; set; }
}

因为目标类型的属性不存在源上,所以AutoMapper也无法完成精确匹配。 我们需要自定义成员映射规则到我们的类型映射配置上面。

// 源对象
var calendarEvent = new CalendarEvent
{
Date = new DateTime(, , , , , ),
Title = "假期公司聚会"
}; // 配置AutoMapper。 dest是目标表达式。opt是源表达式
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))
.ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))
.ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute)); // 执行映射
CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent); form.EventDate.ShouldEqual(new DateTime(, , ));
form.EventHour.ShouldEqual();
form.EventMinute.ShouldEqual();
form.Title.ShouldEqual("假期公司聚会");

ForMember方法允许我们指定2个action委托去配置每个成员的映射关系。 在上面的例子中,我们在源表达式使用了MapFrom方法去执行源值与目标成员的映射。这个MapFrom方法接受一个lambda表达式为参数,它在对象映射期间进行求值,即惰性求值。MapFrom参数可以是任意一个func的lambda表达式。

验证配置(Configuration validation)

平常我们手工进行对象映射,虽然很枯燥无味,但有利于我们测试转换。在这个源类型到目标类型转换基础测试上,其实我们仍然需要测试自己的应用。 AutoMapper也想到了这点,它减少的不仅仅是我们手工进行对象映射的事情,还能帮助我们节省手工写测试代码的时间。

AutoMapper提供了AssertConfigurationIsValid方法去测试我们的配置项。 假设我们有个轻微的错误在源类型和目标类型上:

public class Source 
{
public int SomeValue { get; set; }
}
public class Destination
{
public int SomeValuefff { get; set; }
}

在Destination上,我们可能不小心输入错误,多了几个fff。也可能是我们的源属性重命名了。

我们去测试配置项,创建映射配置并且执行AssertConfigurationIsValid方法。

Mapper.CreateMap<Source, Destination>();
Mapper.AssertConfigurationIsValid();

在代码执行期间会抛出一个AutoMapperConfigurationException异常,描述消息为:

 Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
==============================================================
Source -> Destination (Destination member list)
ConsoleApplication1.Source -> ConsoleApplication1.Destination (Destination member list)
Unmapped properties:
SomeValuefff

AssertConfigurationIsValid执行验证期间,AutoMapper会检查每个目标类型的属性,逐一去匹配源中是否存在合适相等的类型。

异常处理(Overriding configuration errors)

除了我们去修改源和目标类型的名称外。 我们有3种选择去解决错误:

  • 自定义值解析器
  • 指定字段映射(Projection)
  • 使用忽略(Ignore())选项

关于第三种选择,在目标类型我们有个成员,它有其他的含义(非字面意思或预留字段), 我们不想进行转换,我们可以配置如下:

 Mapper.CreateMap<Source, Destination>()
.ForMember(dest => dest.SomeValuefff, opt => opt.Ignore());

官方文档:https://github.com/AutoMapper/AutoMapper

坐车回家过年了,祝大家新年愉快。

AutoMapper使用手册(一)的更多相关文章

  1. 【C#】AutoMapper 使用手册

    目录 1 入门例子 2 注册 2.1 Profile 3 配置 3.1 命名约定 3.2 配置可见性 3.3 全局属性/字段过滤 3.4 识别前缀和后缀 3.5 替换字符 4 调用构造函数 5 数组和 ...

  2. 恋爱虽易,相处不易:当EntityFramework爱上AutoMapper

    剧情开始 为何相爱? 相处的问题? 女人的伟大? 剧情收尾? 有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易 ...

  3. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  4. AutoMapper

    什么是AutoMapper? AutoMapper是一个对象和对象间的映射器.对象与对象的映射是通过转变一种类型的输入对象为一种不同类型的输出对象工作的.让AutoMapper有意思的地方在于它提供了 ...

  5. FREERTOS 手册阅读笔记

    郑重声明,版权所有! 转载需说明. FREERTOS堆栈大小的单位是word,不是byte. 根据处理器架构优化系统的任务优先级不能超过32,If the architecture optimized ...

  6. AutoMapper随笔记

    平台之大势何人能挡? 带着你的Net飞奔吧! http://www.cnblogs.com/dunitian/p/4822808.html#skill 先看效果:(完整Demo:https://git ...

  7. AutoMapper:Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type

    异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html 应用场景:ViewModel==>Mode映射的时候出错 AutoMappe ...

  8. JS魔法堂:不完全国际化&本地化手册 之 理論篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  9. AutoMapper的介绍与使用(一)

    软件环境 vs2015 asp.net mvc 5 .NET Framework 4.5.2 AutoMapper 5.2.0.0 AutoMapper安装 新建asp.net mvc 项目 Auto ...

随机推荐

  1. fat32转ntfs

    convert c: /fs:ntfs 下了个维基的zim,7G,fat32放不下 :( Microsoft Windows [版本 6.1.7600] 版权所有 (c) 2009 Microsoft ...

  2. php字符串匹配

    $a='abcdef'; $b='abc'; similar_text($a,$b,$num); $num=3;

  3. axure的一些注意事项

    1. 不要轻易用中继器的 载入时 事件, 感觉存在bug 2. 元件在显示和隐藏的动画过程中,不要去取他的x,y值,有几率会取成0,也不要去获取它的尺寸,只有在动画完成后才能获得 3. 装着一个中继器 ...

  4. idapython实现动态函数调用批量注释

    部门小伙伴遇到一个样本需要对动态函数调用就行批量注释还原的问题,通过idapython可以大大的减少工作量,其实这一问题也是很多样本分析中最耗时间的一块,下面来看看如何解决这个问题(好吧这才是今年最后 ...

  5. MD5验证

    commons-codec包可以从apache下载:http://commons.apache.org/codec/download_codec.cgi MD5现在是用来作为一种数字签名算法,即A向B ...

  6. spring-aop学习【基于注解】

    我个人觉得,这个好像就是用在定制日志输出上,和log4j很像. 用途: 如果业务方法调用每一步都需要详细的日志,那就用这个吧 好处就是: 方便维护,只包含业务代码 下面开始说明: 所需要的jar包: ...

  7. TMemo.Text 回车键会变成#$D#$A,而非#13#10

    mmoComplain: TMemo;//cxmComplain.Text 会造成回车键 转换成十六进制的字符串 #$D#$A,而非#13#10 //cxmComplain.Text范例:'风发的是' ...

  8. 【Python装饰者】在函数测试的作用

    [引言] 我们经常需要多函数进行耗时测试,测试方法有许多,这里介绍装饰者的方法,提高耗时测试代码的可复用性,在其他方面的应用也是如此. [设计原则] 类应该对扩展开放,对修改关闭. [代码] (1)定 ...

  9. HDU5509 : Pattern String

    只要求出两个字符串的最小表示,然后就可以判断是否循环同构. 枚举最小表示的开头在哪个位置,然后求出Hash值,如果两个串的Hash值集合有交,那么说明循环同构. 因为串经过压缩,原串的长度很大,不能直 ...

  10. linux中shell变量$#,$@,$0,$1,$2的含义解释

    linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...