官網:http://automapper.org/ 文檔:https://automapper.readthedocs.io/en/latest/index.html GitHub:https://github.com/AutoMapper/AutoMapper/blob/master/docs/i ...
文檔:https://automapper.readthedocs.io/en/latest/index.html
GitHub:https://github.com/AutoMapper/AutoMapper/blob/master/docs/index.rst
什麼是AutoMapper?
AutoMapper是一個對象-對象映射器。對象-對象映射通過將一種類型的輸入對象轉換為另一種類型的輸出對象來工作。使AutoMapper變得有趣的是,它提供了一些有趣的約定,以免去搞清楚如何將類型A映射為類型B。只要類型B遵循AutoMapper既定的約定,就需要幾乎零配置來映射兩個類型。
為什麼要使用AutoMapper?
映射代碼很無聊。測試映射代碼更加無聊。AutoMapper提供了簡單的類型配置以及簡單的映射測試。真正的問題可能是“為什麼使用對象-對象映射?”映射可以在應用程式中的許多地方發生,但主要發生在層之間的邊界中,例如UI /域層或服務/域層之間。一層的關註點通常與另一層的關註點衝突,因此對象-對象映射導致分離的模型,其中每一層的關註點僅會影響該層中的類型。
AutoMapper的使用場景:
AutoMapper是對象到對象的映射工具。在完成映射規則之後,AutoMapper可以將源對象轉換為目標對象。
一般情況下,表現層與應用層之間是通過DTO(數據傳輸對象Data Transfer Object)來進行交互的,數據傳輸對象是沒有行為的POCO對象(簡單CLR對象Plain Old CLR Object),他的目的是為了對領域對象進行數據封裝,實現層與層之間的數據傳遞。為何不直接將領域對象進行數據傳遞?因為領域對象更註重領域,DTO更註重數據。由於“富領域模型”的特點,這樣會直接將領域對象的行為暴露給表現層。
DTO本身不是業務對象,它是根據UI需求進行設計的。簡單來說Model面向業務,我們是通過業務來定義Model的。而DTO是面向UI,通過UI的需求來定義的,通過DTO我們實現了表現層與Model層之間的解耦,表現層不引用Model。如果開發過程中我們的模型變了,而界面沒變,我們只需改Model而不需要去改動表現層。
如何使用AutoMapper?
首先,您需要同時使用源類型和目標類型。目標類型的設計可能會受到其所在層的影響,但是只要成員名稱與源類型的成員匹配,AutoMapper的效果最佳。如果您有一個名為“ FirstName”的源成員,它將自動映射到名稱為“ FirstName”的目標成員。AutoMapper還支持Flattening。
將源映射到目標時,AutoMapper將忽略空引用異常。這是設計使然。如果您不喜歡這種方法,則可以根據需要將AutoMapper的方法與自定義值解析器結合使用。
如何在Dotnet Core中使用AutoMapper?
首先,要安裝依賴包:
在Startup.cs中利用Dotnet Core自帶的容器進行註入,因為我裡面是示例代碼,新建的示例Demo也沒有去改名字,也都是在同一個命名空間下的,但是在實際項目中是不會出現這種問題的
//添加對AutoMapper的支持 services.AddAutoMapper(Assembly.Load("WebApplication1"), Assembly.Load("WebApplication1"));
即下圖所示的關係:
源類型Model對象,與映射後的DTO類型:
public class UserInfo { public string UserName { get; set; } public string UserPwd { get; set; } public string GetCreateTime { get; set; } }
public class UserInfoDTO { public string UserName { get; set; } public string UserPwd { get; set; } public string Role { get; set; } public DateTime CreateTime { get; set; } public string TestTime { get; set; } }
Profile的用法:
Profile提供了一個命名的映射類,所有繼承自Profile類的子類都是一個映射集合。這裡我們創建一個UserProfile繼承Profile類。
CreateMap:創建映射規則。
BeforeMap:在映射之前執行的方法。
AfterMap:反之,映射之後執行的方法。
自動化扁平映射:AutoMapper會將類中的屬性進行分割,或匹配"Get"開頭的方法。
ForMember:指定映射欄位。
public class UserProfile : Profile { //添加你的屍體映射關係 public UserProfile() { CreateMap<UserInfo, UserInfoDTO>() .BeforeMap((source, dto) => { //可以較為精確的控制輸出數據格式 if (string.IsNullOrEmpty(source.GetCreateTime)) { source.GetCreateTime = Convert.ToDateTime(source.GetCreateTime).ToString("yyyy-MM-dd"); } }) //指定映射欄位。將UserInfo.GetCreateTime映射到UserInfoDTO.TestTime .ForMember(dto => dto.TestTime, opt => opt.MapFrom(info => info.GetCreateTime)) .ForMember(dto => dto.Role, opt => opt.Ignore()) .ForMember(dto => dto.CreateTime, opt => opt.Ignore()); CreateMap<StudentInfo, UserInfo>(); } }
控制器註入IMapper:
private readonly IMapper _mapper; public HomeController(IMapper mapper) { _mapper = mapper; }
單個對象轉DTO:
//模擬數據 var user = new UserInfo() { UserName = "bingle", UserPwd = "12345" }; var userDto = _mapper.Map<UserInfoDTO>(user);
集合轉Dto集合:
//模擬數據 var userList = new List<UserInfo> { new UserInfo { UserName="bingle_1", UserPwd="1" }, new UserInfo { UserName="bingle_2", UserPwd="2" }, new UserInfo { UserName="bingle_3", UserPwd="3" }, new UserInfo { UserName="bingle_4", UserPwd="4" }, new UserInfo { UserName="bingle_5", UserPwd="5" }, new UserInfo { UserName="bingle_6", UserPwd="6" } }; //對象集合轉Dto集合 var usersDtos = _mapper.Map<List<UserInfoDTO>>(userList);
AutoMapper功能很強大,在這邊介紹的只是很少的功能,有興趣的伙伴可以去AutoMapper官方文檔深入學習。
如果有小伙伴覺得在使用AutoMapper都得在Controller的構造函數中進行註入一遍麻煩的話,AutoMapper也是支持這種映射方式如:Mapper.Map
實例方式:
//模擬數據 var user = new UserInfo() { UserName = "bingle", UserPwd = "12345" }; var config = new MapperConfiguration(cfg => cfg.CreateMap<UserInfo, UserInfoDTO>()); var mapper = config.CreateMapper(); var userDTO = mapper.Map<UserInfoDTO>(user);
參考:https://blog.csdn.net/weixin_37207795/article/details/81009878