返回总目录


自定义值解析

虽然AutoMapper覆盖了相当一部分目标成员的映射场景,但是还有 1-5%的目标值需要解析处理一下。很多时候,自定义的值解析是可以放在领域层的领域逻辑。然而,如果该逻辑只是和映射操作有关的话,那它就会应为一些不必要的行为使得源类型很凌乱。这种场合,AutoMapper允许我们为目标成员配置自定义的值解析器。

举个栗子,有两个类Source和Destination,定义如下:

public class Source
{
public int Value1 { get; set; }
public int Value2 { get; set; }
}
public class Destination
{
public int Total { get; set; }
}

我们想要在映射期间产生一个计算的值,也就是说,在Source到Destination映射的过程中,把Source的两个属性值加起来赋给Destination的属性。由于某些原因,我们不能把这个逻辑放到源类型里,为了提供一个自定义值解析器,我们首先需要创建一个实现了IValueResolver:

public class MyValueResolver : IValueResolver
{ public ResolutionResult Resolve(ResolutionResult source)
{
//TODO:实现逻辑
}
}

ResolutionContext包含了当前解析操作的所有上下文信息,如源类型,源值等等。大多数场合,我们不需要这个更高级的接口。另一种方法,我们可以实现抽象类ValueResolver<TSource, TDestination>:

public class MyValueResolver : ValueResolver<Source, int>
{ protected override int ResolveCore(Source source)
{
return source.Value1 + source.Value2;
}
}

现在,我们已经实现了自己的值解析器,接下来就需要告诉AutoMapper,当解析一个特定的目标成员时,要使用这个自定义的值解析器。有3中方式告诉AutoMapper如何使用自定义解析器,包括:

  • ResolveUsing<TValueResolver>
  • ResolveUsing(typeof(CustomValueResolver))
  • ResolveUsing(aValueResolverInstance)

接下来,我们就开始使用自己的值解析器:

class Program
{
static void Main(string[] args)
{
Mapper.CreateMap<Source, Destination>().ForMember(dest => dest.Total, opt =>
{
opt.ResolveUsing<MyValueResolver>();
}); var src = new Source {Value1 = , Value2 = }; var destObj= Mapper.Map<Destination>(src);
Console.WriteLine("destObj.Total={0}", destObj.Total);
Console.Read();
}
}

虽然目标成员Total没有任何匹配的源成员,但是我们给它添加了有效配置的自定义解析器,解析器就会对目标成员值的提供负责。

测试成功,结果如下:

自定义构造函数方法

因为我们只提供了自定义的解析器类型给AutoMapper,所以映射引擎会使用反射创建该值解析器的实例。如果我们不想要AutoMapper使用反射创建实例,我们要么直接提供一个实例,要么使用ConstruceBy方法来提供一个自定义的构造函数方法:

Mapper.CreateMap<Source, Destination>().ForMember(dest => dest.Total, opt =>
{
opt.ResolveUsing<MyValueResolver>().ConstructedBy(()=>new MyValueResolver());
});

在映射操作期间,AutoMapper不使用反射,直接执行此回调函数。这在解析器可能需要构造函数参数或者需要通过Ioc容器构建的时候很有用。

这里不再做演示,有兴趣的小伙伴可自行研究。

AutoMapper(四)的更多相关文章

  1. Asp.net 面向接口可扩展框架之使用“类型转化基础服务”测试四种Mapper(AutoMapper、EmitMapper、NLiteMapper及TinyMapper)

    Asp.net 面向接口可扩展框架的“类型转化基础服务”是我认为除了“核心容器”之外最为重要的组成部分 但是前面博文一出,争议很多,为此我再写一篇类型转化基础服务和各种Mapper结合的例子,顺便对各 ...

  2. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](四)

    前言 上一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)>,我们完成了: * 引用SqlSugar * ...

  3. DTO学习系列之AutoMapper(四)

    本篇目录: Mapping Inheritance-映射继承 Queryable Extensions (LINQ)-扩展查询表达式 Configuration-配置 Conditional Mapp ...

  4. .NetCore学习笔记:四、AutoMapper对象映射

    什么是AutoMapper?AutoMapper是一个简单的小型库,用于解决一个看似复杂的问题 - 摆脱将一个对象映射到另一个对象的代码.这种类型的代码是相当沉闷和无聊的写,所以为什么不发明一个工具来 ...

  5. AutoMapper(六)

    返回总目录 List和数组 AutoMapper只要求元素类型的配置而不要求可能会用到的任何数组或者list类型.比如,我们有一个简单的源和目标类型: public class Source{ pub ...

  6. 使用Adminlite + ASP.NET MVC5(C#) + Entityframework + AutoFac + AutoMapper写了个api接口文档管理系统

    一.演示: 接口查看:http://apidoc.docode.top/ 接口后台:http://apiadmin.docode.top/ 登录:administrator,123456 二.使用到的 ...

  7. 对象映射工具AutoMapper介绍

    AutoMapper是用来解决对象之间映射转换的类库.对于我们开发人员来说,写对象之间互相转换的代码是一件极其浪费生命的事情,AutoMapper能够帮助我们节省不少时间. 一. AutoMapper ...

  8. C#进阶系列——DDD领域驱动设计初探(四):WCF搭建

    前言:前面三篇分享了下DDD里面的两个主要特性:聚合和仓储.领域层的搭建基本完成,当然还涉及到领域事件和领域服务的部分,后面再项目搭建的过程中慢慢引入,博主的思路是先将整个架构走通,然后一步一步来添加 ...

  9. C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用

    前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...

随机推荐

  1. ABP文档 - 导航

    文档目录 本节内容: 创建菜单 注册导航供应器 显示菜单 每个web应用都有一些菜单用来在页面/屏幕之间导航,ABP提供了一个通用的基础框架创建并显示菜单给用户. 创建菜单 一个应用可能由不同模块组成 ...

  2. 【java】Naming.bind和Registry.bind区别

    Naming类和Registry类均在java.rmi包 Naming类通过解析URI绑定远程对象,将URI拆分成主机.端口和远程对象名称,使用的仍是Registry类. public static ...

  3. web全栈开发之网站开发二(弹出式登录注册框前端实现-类腾讯)

    这次给大家分享的是目前很多网站中流行的弹出式登录框,如下面的腾讯网登录界面,采用弹出式登录的好处是大大提升了网站的用户体验和交互性,用户不用重新跳转到指定的页面就能登录,非常方便 先来个演示地址 要实 ...

  4. potrace源码分析一

    1 简介 potrace是由Dalhousie University的Peter Selinger开发一款位图轮廓矢量化软件,该软件源码是可以公开下载的,详细见项目主页:http://potrace. ...

  5. 【JS基础】对象

    delete 可以删除对象属性及变量 function fun(){ this.name = 'mm'; } var obj = new fun(); console.log(obj.name);// ...

  6. Spark-shell和Spark-Submit的使用

    Spark-shell有两种使用方式: 1:直接Spark-shell 会启动一个SparkSubmit进程来模拟Spark运行环境,是一个单机版的. 2:Spark-shell --master S ...

  7. [AlwaysOn Availability Groups]健康模型 Part 1——概述

    健康模型概述 在成功部署AG之后,跟踪和维护健康状况是很重要的. 1.AG健康模型概述 AG的健康模型是基于策略管理(Policy Based Management PBM)的.如果不熟悉这个特性,可 ...

  8. Linux基础介绍【第四篇】

    Linux文件和目录的属性及权限 命令: [root@oldboy ~]# ls -lhi total 40K 24973 -rw-------. 1 root root 1.1K Dec 10 16 ...

  9. python select网络编程详细介绍

    刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...

  10. 玩转 Linux 系统的方法论

    Linus 说“Just for fun”,而我要说“Just for 折腾”.想知道我是怎样折腾 Linux 的,请看下面这个截图: 从这个截图可以看出,我为了“折腾” Linux 系统,在我的电脑 ...