出处:http://www.cnblogs.com/WeiGe/p/3835523.html

先说说DTO

DTO是个什么东东?

DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已。

为什么要用DTO?

1、DTO更注重数据,对领域对象进行合理封装,从而不会将领域对象的行为过分暴露给表现层

2、DTO是面向UI的需求而设计的,而领域模型是面向业务而设计的。因此DTO更适合于和表现层的交互,通过DTO我们实现了表现层与领域Model之间的解耦,因此改动领域Model不会影响UI层

3、DTO说白了就是数据而已,不包含任何的业务逻辑,属于瘦身型的对象,使用时可以根据不同的UI需求进行灵活的运用

AutoMapper

现在我们既然知道了使用DTO的好处,那么我们肯定也想马上使用它,但是这里会牵扯一个问题:怎样实现DTO和领域Model之间的转换?

有两个思路,我们要么自己写转换代码,要么使用工具。不过就应用而言,我还是觉得用工具比较简单快捷,那就使用工具吧。其实这样的转换工具很多,不过我还是决定使用AutoMapper,因为它足够轻量级,而且也非常流行,国外的大牛们都使用它。使用AutoMapper可以很方便的实现DTO和领域Model之间的转换,它是一个强大的Object-Object Mapping工具。

一、如何添加AutoMapper到项目中?

在vs中使用打开工具-库程序包管理器-程序包管理控制平台,输入“Install-Package AutoMapper”命令,就可以把AutoMapper添加到项目中了~

二、吃点栗子

栗子1(两个类型之间的映射)

Mapper.CreateMap<AddressDto, Address>();
             AddressDto dto = new AddressDto
              {
                  Country = "China",
                  City = "ShangHai",
                  Street = "JinZhong Street"
              };
Address address = Mapper.Map<AddressDto,Address>(Dto);

栗子2(两个映射的对象有部分字段名称不一样)

AddressDto到Address的映射,AddressDto的字段CountryName要对应Address的字段Country:

Mapper.CreateMap<AddressDto, Address>(). ForMember(d => d.Country, opt => opt.MapFrom(s => s.CountryName));

栗子3(列表类型之间的映射)

源类型List<Address>,目标类型List<AddressDto>:

AutoMapper.Mapper.CreateMap< Address, AddressDto >();
var addressDtoList = AutoMapper.Mapper.Map<List< Address >, List< AddressDto >>( addressList);

栗子4(映射在增改查中的应用)

public class ProductBll

{
        Public IProductRepository productRepository{ set; get; }
        public ProductDTO CreateProduct(ProductDTO productDTO)
        {
            Mapper.CreateMap<ProductDTO, Product>();
            Product product = Mapper.Map<ProductDTO, Product>(productDTO);
            productRepository.AddProduct(product);
            return productDTO;
        }

public List<ProductDTO> GetProduct() { Mapper.CreateMap<Product, ProductDTO>(); List<ProductDTO> arr = new List<ProductDTO>(); productRepository.GetProduct().ForEach(i => { arr.Add(Mapper.Map<Product, ProductDTO>(i)); }); return arr; } public ProductDTO ModifyProduct(ProductDTO productDTO) { Mapper.CreateMap<ProductDTO, Product>(); Product product = Mapper.Map<ProductDTO, Product>(productDTO); productRepository.ModifyProduct(product); return productDTO; } }

三、让AutoMapper使用变得简单

吃过上面的栗子,你觉得怎么样呢?如果想继续吃,那就去查看AutoMapper的具体API文档吧!倘若在项目中真正要用的时候,我觉得还是应该对AutoMapper的方法进行一些整理,最好能够封装一下,这里我通过扩展方法的形式将其封装为AutoMapperHelper,这样以后使用AutoMapper就变的SO EASY了~

using System.Collections;
using System.Collections.Generic;
using System.Data;
using AutoMapper;
namespace Infrastructure.Utility

{
    /// <summary>
    /// AutoMapper扩展帮助类
    /// </summary>
    public static class AutoMapperHelper
    {
        /// <summary>
        ///  类型映射
        /// </summary>
public static T MapTo<T>(this object obj) { if (obj == null) return default(T); Mapper.CreateMap(obj.GetType(), typeof(T)); return Mapper.Map<T>(obj); } /// <summary> /// 集合列表类型映射 /// </summary>
public static List<TDestination> MapToList<TDestination>(this IEnumerable source) { foreach (var first in source) { var type = first.GetType(); Mapper.CreateMap(type, typeof(TDestination)); break; } return Mapper.Map<List<TDestination>>(source); } /// <summary> /// 集合列表类型映射 /// </summary>
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source) { //IEnumerable<T> 类型需要创建元素的映射 Mapper.CreateMap<TSource, TDestination>(); return Mapper.Map<List<TDestination>>(source); } /// <summary> /// 类型映射 /// </summary>
public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination) where TSource : class where TDestination : class { if (source == null) return destination; Mapper.CreateMap<TSource, TDestination>(); return Mapper.Map(source, destination); } /// <summary> /// DataReader映射 /// </summary>
public static IEnumerable<T> DataReaderMapTo<T>(this IDataReader reader) { Mapper.Reset(); Mapper.CreateMap<IDataReader, IEnumerable<T>>(); return Mapper.Map<IDataReader, IEnumerable<T>>(reader); } } }

你可以像下面的栗子这样使用:

//对象映射
ShipInfoModel shipInfoModel = ShipInfo.MapTo<ShipInfoModel>();
//列表映射
List< ShipInfoModel > shipInfoModellist = ShipInfoList.MapToList<ShipInfoModel>();

小结

在项目中多使用DTO实现表现层与领域Model的解耦,用AutoMapper来实现DTO与领域Model的相互转换,让AutoMapper在你的项目里飞一会儿

让AutoMapper在你的项目里飞一会儿(转)的更多相关文章

  1. 让AutoMapper在你的项目里飞一会儿

    先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对 ...

  2. AutoMapper 在你的项目里飞一会儿

    先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对 ...

  3. 如何把Spring制作成jar包,然后在项目里运行。

    第一步:首先我们先把Spring的代码准备好.如图一 (图1). 第二步:我们在桌面新建一个文件夹,如图二 (图2). 我们要在这个文件夹里新建两个夹,一个文件夹是你项目的包名,也就是我们图1的aop ...

  4. ANDROID STDUIO 项目里的R文件突然丢失的解决办法N种之一

    刚刚项目里的R文件突然挂了,清理项目,关闭重开Studio,都不能解决.快没折了. 然后只好在项目上右击,看看有没有解决的办法.发现有个 Make Module ,姑且试试吧. 结果,竟然修复了.这是 ...

  5. 在asp.net mvc4项目里bootstrap datetimepicker控件的使用

    前段时间写了一篇关于调用阿里大于的短信接口来开发例会短信群发通知功能的文章http://www.cnblogs.com/zhouyuangan/p/apicall_1.html,其中的例会时间是需求中 ...

  6. 在Android Studio和Android Eclipse 更改现有项目里的SDK版本

    一,在Eclipse下改项目里的SDK的版本方法有几种,都比较简单:1.右键单击项目--->properties---->Resource----->Android在Project ...

  7. 项目里的jquery.min.js错误

    项目里的jquery.min.js报一系列 - Missing semicolon - Missing semicolon - Missing semicolon - Missing semicolo ...

  8. [Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code

    [Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code 问题情景 开发Cordova Plugin的时候,开发的流程应该是: 建立Cordova Plug ...

  9. eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法

    eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法 当使用eclipse导入外部的web工程时,有时会提示HttpServletRequest, Serv ...

随机推荐

  1. vs2008编译wxWidgets 2.8.12

    用vs2008编译wxWidgets 2.8.12 FileZilla客户端源码3.5.3及以上版本依赖wxWidgets 2.8.12或更高版本,因此,编译FileZilla客户端首先需要编译wxW ...

  2. CodeForces 702D Road to Post Office

    答案的来源不外乎于3种情况: 纯粹走路,用时记为${t_1}$:纯粹乘车,用时记为${t_2}$:乘车一定距离,然后走路,用时记为${t_3}$. 但是${t_1}$显然不可能成为最优解. 前两个时间 ...

  3. Paint on a Wall

    Paint on a Wall 题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4012 搜索+状态压缩 这题刚开始以为是dp(之前写过墙是一 ...

  4. iOS开发tableview二级联动的细节实现中注意的细节总结

    首先说网络慢带来的数据显示问题 可以通过判断请求参数是否一致来刷新tableview. SJBCategaryModel * categaryModel = self.categarys[Catega ...

  5. Sass与Compress实战:第七章

    概要:将介绍Compass如何让你从本地开发原型轻松转移到生产环境的网址或Web应用中. 本章内容: ● 生成资源URL的最佳实践 ● 撰写无需Web服务器的样式表 ● 在浏览器中进行设计的技巧 ● ...

  6. KindeEditor图片上传插件用法

    因业务需要找了款插件 KindeEditor编辑器确认挺好用,但无奈技术有限,上传配置不知,故问度娘! 图片上传对于部分新手来说有时候是一件非常头疼的事,今天来分享一下项目中使用到的这个插件Kinde ...

  7. putty完全使用手册--多窗口---git提交---连接数据库--自动日志显示

    01 putty dev 192.168.3.38 02 cd /home/gongfu/tripb/cranedev02.1 git status git add git commit git pu ...

  8. HTML5 学习总结

    1,h5比原来的h4.0版本的页面头部更为简化, <!doctype html> <meta charset="utf-8"/>sublime中快速生成格式 ...

  9. 我使用的Bash脚本模板

    在Linux环境下(包括在相应的模拟环境,如Windows中的Cygwin)工作的时间久了,就会慢慢积累出一些自己写的小脚本程序,用于加速日常的操作与工作流程,如自动挂载与卸载U盘,映射网络驱动器,数 ...

  10. Openjudge-计算概论(A)-角谷猜想

    描述: 所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘3加1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到1.如,假定初始整数为5,计算过程分别为16.8.4.2.1 ...