讓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
在你的專案裡飛一會兒
相關文章
- 細緻入微 | 讓 SQL 優化再多飛一會兒SQL優化
- 那個程式猿說你呢,先讓BUG飛一會兒
- 讓NodeJS在你的專案中發光發熱NodeJS
- 在你的 Flutter 專案中隱藏敏感資訊Flutter
- SpringBoot 深度調優,讓你的專案飛起來!Spring Boot
- 專案裡的一些小函式函式
- 知道策略模式!但不會在專案裡使用?模式
- 從零開始的.NET專案(一)倉儲模式與配置AutoMapper模式APP
- python 打飛機專案 ( 讓敵機發射子彈 )Python
- 在你的專案管理中,運用報表分析了嗎?專案管理
- 飛機小專案
- 路飛專案1.0
- 什麼樣的專案經歷會讓面試官眼前一亮面試
- 如果讓我完善幾年前的一個專案,我會做哪些改進?
- 測試會開發技術在你的職業生涯裡真的那麼重要嗎?
- IT專案管理那些事兒專案管理
- 讓子彈再飛一會:遊戲中關於碰撞體積的趣聞遊戲
- Angular 專案裡使用 scss 檔案的一些技巧AngularCSS
- 《IT專案管理那些事兒》——前言專案管理
- 飛項的5種應用方法,幫助你輕鬆學會專案管理!專案管理
- AutoMapper(一)APP
- 在你的JDeveloper裡擴充套件J2ME (轉)Developer套件
- 讓 F5 歇一會兒——Laravel-mix 自動重新整理之道Laravel
- 關於專案管理的一點體會專案管理
- 讓蔡 xu 坤在你的命令列中打籃球命令列
- 《IT專案管理那些事兒》——前言薦專案管理
- 7個Python實戰專案程式碼,讓你感受下大神是如何起飛的!Python
- 開始一個新專案前,應當想清楚的幾件事兒
- USACO第一題RIDE,我的飛船在哪裡IDE
- 測試在專案流程中的那些事兒
- 這些新技術總有一天會穿在你身上
- 節假日裡的專案管理(轉)專案管理
- “藍眼睛”裡的外包專案(轉)
- luffy路飛專案上線03
- 如果讓你主導一款女性向遊戲專案,你會怎麼設計?遊戲
- 讓前端的子彈飛-TypeScript前端TypeScript
- 看學徒體會專案管理(一)專案管理
- 讓你的Rails專案保持清潔AI