官網:http://automapper.org/html
文檔:https://automapper.readthedocs.io/en/latest/index.htmlgit
GitHub:https://github.com/AutoMapper/AutoMapper/blob/master/docs/index.rstgithub
什麼是AutoMapper?app
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而不須要去改動表現層。spa
如何使用AutoMapper?.net
首先,您須要同時使用源類型和目標類型。目標類型的設計可能會受到其所在層的影響,可是隻要成員名稱與源類型的成員匹配,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