AutoMapper 在你的项目里飞一会儿
先说说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 在你的项目里飞一会儿的更多相关文章
- 让AutoMapper在你的项目里飞一会儿(转)
出处:http://www.cnblogs.com/WeiGe/p/3835523.html 先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说 ...
- 让AutoMapper在你的项目里飞一会儿
先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对 ...
- 如何把Spring制作成jar包,然后在项目里运行。
第一步:首先我们先把Spring的代码准备好.如图一 (图1). 第二步:我们在桌面新建一个文件夹,如图二 (图2). 我们要在这个文件夹里新建两个夹,一个文件夹是你项目的包名,也就是我们图1的aop ...
- ANDROID STDUIO 项目里的R文件突然丢失的解决办法N种之一
刚刚项目里的R文件突然挂了,清理项目,关闭重开Studio,都不能解决.快没折了. 然后只好在项目上右击,看看有没有解决的办法.发现有个 Make Module ,姑且试试吧. 结果,竟然修复了.这是 ...
- 在asp.net mvc4项目里bootstrap datetimepicker控件的使用
前段时间写了一篇关于调用阿里大于的短信接口来开发例会短信群发通知功能的文章http://www.cnblogs.com/zhouyuangan/p/apicall_1.html,其中的例会时间是需求中 ...
- 在Android Studio和Android Eclipse 更改现有项目里的SDK版本
一,在Eclipse下改项目里的SDK的版本方法有几种,都比较简单:1.右键单击项目--->properties---->Resource----->Android在Project ...
- 项目里的jquery.min.js错误
项目里的jquery.min.js报一系列 - Missing semicolon - Missing semicolon - Missing semicolon - Missing semicolo ...
- [Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code
[Cordova] 无法编译Visual Studio项目里Plugin副本的Native Code 问题情景 开发Cordova Plugin的时候,开发的流程应该是: 建立Cordova Plug ...
- eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法
eclipse项目中关于导入的项目里提示HttpServletRequest 不能引用的解决办法 当使用eclipse导入外部的web工程时,有时会提示HttpServletRequest, Serv ...
随机推荐
- CentOS7.6安装Go-1.12.9
安装步骤 Go的官网:https://golang.google.cn 1. 下载压缩包 wget https://dl.google.com/go/go1.12.9.linux-amd64.tar. ...
- ORACLE check view
select owner as schema_name, view_name from sys.all_views where VIEW_NAME like 'P%' order by ...
- libevent使用IOCP网络模型的示例
这段时间抽空学习了一下强大的网络库libevent,其使用标准C语言编写,支持Windows.Linux.Mac等等主流操作系统,早期版本不支持Windows的IOCP,最新版本已经添加上了,在网上找 ...
- 深度探索C++对象模型读书笔记-第七章站在对象模型的尖端
Template 模板是在编译时期而非执行时期被计算的.因此其不会带来效率的降低. 1: const Point<float> &ref = 0; 该语句会实例化一个Point的f ...
- java中的.java和.class的区别
java文件就是这样一个未经编译的源程序,一般是给程序员看的. class文件就是被编译器编译过的java文件,通常是给计算机看的.
- 了解GTIN小记
GTIN为条形码,即"全球贸易项目代码"(Global Trade Item Number ) GTIN用作识别商品品项的全球性独一编码,是编码系统中应用最广泛的标识代码. GTI ...
- python 获取年月日时分秒 获取当前时间 datetime函数
import datetime#取当前时间print(datetime.datetime.now())#取年print(datetime.datetime.now().year)#取月print(da ...
- PDO::beginTransaction
语法 bool PDO::beginTransaction ( void ) 关闭自动提交模式.自动提交模式被关闭的同时,通过 PDO 对象实例对数据库做出的更改直到调用 PDO::commit() ...
- 01二维背包+bitset优化——hdu5890
口胡一种别的解法: 三重退背包,g1[j]k]表示不选x的选了j件物品,体积为k的方案数,g[0][0] = 1 , g1[j][k]=dp[j][k]-g1[j-1][k-a[x]] 然后按这样再退 ...
- 移动端多选插件-jquery
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...