AutoMapper

Dto与EF实体之间的转换用AutoMapper会变的很方便、很高效,是大多数项目的选择。博主本人的项目也在使用AutoMapper这个组件

好用归好用,但是想要把它用好又是另一事了。AutoMapper需我们去配置映射才可以去进行Map转换,下面有Person类与对应的Dto类

public class Person
{
public string Name { get; set; } public string Age { get; set; }
} public class PersonDto
{
public string Name { get; set; } public string Age { get; set; }
}

按照官方使用方式,我们需要以下几个步骤

         //配置映射
Mapper.Initialize(o =>
{
o.CreateMap<Person, PersonDto>();
o.CreateMap<PersonDto, Person>();
});
var p = new Person { Age = "20", Name = "小明" };
//进行转换
var pDto = Mapper.Map<PersonDto>(p);

当然,上面的使用方式没有什么问题,似乎也很简单。但是对于一个项目来说几十成百的表已经是家常便饭,对于种配置方式会不会很蛋疼呢。想象一些一堆的CreateMap就会让人恶心,我也看到现在有一些解决方案,即对映射进行粒化每一个相关的功能或实体创建Profile类,添加到Profile集合中。在程序运行时统一注册。这样也不错,但是还是会去写一堆的Profile类和CreateMap。

使用Atturibute进行配置映射

在abp中看到了使用特性的方式进行配置映射,简单的一行代码就可以解决问题,但是似乎在没有使用abp的项目里并不是那么使用这种方式,所以我就借鉴了这种方法写了一个属于自己的特性

[AutoMapFrom(typeof(Person))]

首先是创建一个类去继承自Attribute,这是很简单的。在实际项目中不一定都是一个实体对应一个dto的情况,还会有一个实体对应多个dto的情况存在,所以toSource应该是一个数组

public class AutoMapAttribute : Attribute
{
public Type[] ToSource { get; private set; } public AutoMapAttribute(params Type[] toSource)
{
this.ToSource = toSource;
}
}

后面的代码就更为简单了,我们拿到DTO的程序集,(视项目程序集名而定) ,然后拿到所有的自定义类型判断其中的type是否有贴上了AutoMapAttribute类,如果有的话,创建它的实例,拿到source,然后进行创建映射。很简单对吧。

public class AutoMapperModule
{
public static void Init()
{
//拿到dto程序集
var asm = Assembly.Load("DTO"); //拿到自定义的类型
var types = asm.GetExportedTypes();
//创建映射
Mapper.Initialize(o =>
{
foreach (var type in types)
{
//判断是否贴上了AutoMapAttribute
if (!type.IsDefined(typeof(AutoMapAttribute))) continue;
var autoMapper = type.GetCustomAttribute<AutoMapAttribute>(); foreach (var source in autoMapper.ToSource)
{
o.CreateMap(type, source);
o.CreateMap(source, type);
}
}
});
}
}

最后我们需要在程序启动时去加载这些配置,一切就大功告成了。

       protected void Application_Start()
{
//初始化AutoMapper
AutoMapperModule.Init();
}

Map的转换

官网提供的方式是使用Mapper.Map的方式进行转换,假如有一天出现一个更吊,速度更快的开源组件。这个时候我们的项目已经和AutoMapper产生了严重的依赖导致替换会变的很吃力,而且Mapper.Map这种方式也并不是那么的简洁好用。所以写一个Map是势在必行的

我想要的是方式是在对象上直接点出Map并且使用泛型选择我要转换后的类型,这时候已经想到可以用扩展方法了,是不是很方便呢

public static class AutoMapExtension
{ public static TDestination MapTo<TDestination>(this object source)
{
return Mapper.Map<TDestination>(source);
} public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
{
return Mapper.Map(source, destination);
}
}
static void Main(string[] args)
{ //配置映射
Mapper.Initialize(o =>
{
o.CreateMap<Person, PersonDto>();
o.CreateMap<PersonDto, Person>(); });
var p = new Person { Age = "20", Name = "小明" };
//进行转换
p.MapTo<PersonDto>();
}

让AutoMapper更好用的更多相关文章

  1. Asp.net Core 2.2关于AutoMapper更初级的入门教程

    今天刚看到老张的哲学博客关于AutoMapper的教程,从壹开始前后端分离[ .NET Core2.0 +Vue2.0 ]框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完 ...

  2. 一个比 AutoMapper 更快的模型映射的组件 Mapster

    下面是官方的性能测试 Demo,感性的也可以去 Github 上下载. 贴出代码目的是如果后期直接从自己的博客中在线看. using System; using System.Collections. ...

  3. ABP理论学习之Nuget包

    返回总目录 本篇目录 框架 测试基 ABP已经发布在Nuget上,这里是所有包的列表. 框架 Abp Abp系统的核心包.所有其他的包都依赖这个包. Abp.Web 提供了MVC和Web API都使用 ...

  4. ABP组件包升级

    对于abp的爱好者来说在使用abp上会面临两个问题,第一个是如何上手,第二是如何升级,然而们今天的主题是如何升级abp的组件包.目前我项目版本是0.8.2 通过官网boilerplate生成的项目前端 ...

  5. AutoMapper

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

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

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

  7. 【道德经】漫谈实体、对象、DTO及AutoMapper的使用

    写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...

  8. AutoMapper(一)

    返回总目录 映射前后操作 偶尔有时候,在映射发生之前或之后,你可能需要执行一些自定义的逻辑.这可能是很少见的事情,因为在AutoMapper之外处理这些事情是更明显的.你可以创建一个映射前后的全局操作 ...

  9. AutoMapper(三)

    返回总目录 自定义类型转换 有时,需要完全控制一个类型到另一个类型的转换.一个类型一点都不像另一个类型,而且转换函数已经存在了,在这种情况下,你想要从一个“宽松”的类型转换成一个更强壮的类型,例如一个 ...

随机推荐

  1. mybatis 3.2.7 与 spring mvc 3.x、logback整合

    github上有一个Mybatis-Spring的项目,专门用于辅助完成mybatis与spring的整合,大大简化了整合难度,使用步骤: 准备工作: maven依赖项: <properties ...

  2. Javascript中的循环变量声明,到底应该放在哪儿?

    相信很多Javascript开发者都在声明循环变量时犹豫过var i到底应该放在哪里:放在不同的位置会对程序的运行产生怎样的影响?哪一种方式符合Javascript的语言规范?哪一种方式和ecma标准 ...

  3. js的单引号,双引号,转移符

    这里我们看到想在style后边在插入一个样式的变量,data.cssSytle.a是做边和邮编都是"",并且没有转移符

  4. c++ iterator(迭代器)分类及其使用

    前言: 以下的内容为我阅读c++沉思录18,19,20章的笔记以及自己的想法. 正文: 总所周知,c++的stl中提出了iterator的概念,这是C所没有的.在一般的使用中,iterator的行为很 ...

  5. hibernate的hql查询

    1.概念介绍 1.Query是Hibernate的查询接口,用于从数据存储源查询对象及控制执行查询的过程,Query包装了一个HQL查询语句. 2.HQL是Hibernate Query Langua ...

  6. webkit webApp 开发技术要点总结

    如果你是一名前端er,又想在移动设备上开发出自己的应用,那怎么实现呢?幸好,webkit内核的浏览器能帮助我们完成这一切.接触 webkit webApp的开发已经有一段时间了,现把一些技巧分享给大家 ...

  7. Struts2.3.4.1+Spring3.2.3+Hibernate4.1.9整合

    java教程|Struts2.3.4.1+Spring3.2.3+Hibernate4.1.9整合教程并测试成功一.创建项目二.搭建struts-2.3.4.11.struts2必须的Jar包(放到W ...

  8. python中的二维数组和lamda

    python列表推导式 list=[[0 for i in xrange(3)] for j in xrange(4)] 二维数组 g=lambda x,y:x*y; print g(2,9);

  9. win10 google浏览器设置

    在浏览器地址栏中输入命令: chrome://flags/ 撤销:chrome设置了禁止此页弹出提示框 chrome://settings/contentExceptions#popups

  10. Mysql-windows下修改密码

    忘记密码修改(以下各种方法视情况而使用,本人测试,有些都是案情况才可行,但都是有设置成功过) 注:修改密码成功后一定要记得刷新下权限(否则将导致不能使用当前用户连接) mysql>FLUSH P ...