今天剛看到老張的哲學博客關於AutoMapper的教程,從壹開始先後端分離【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 對象映射使用,項目部署Windows+Linux完整版, 看得我有點暈,我搞不得那個CustomProfile跟AutoMapperProfile是幹什麼用的,可能我水平也比較菜,理解能力差點,而後我經過百度後,發現這個確實就是一個很簡單的東西。html
主要分四步後端
注:我在第一次安裝Nuget包時出現一個比較奇怪的狀況,就是我先安裝的AutoMapper.Extensions.Microsoft.DependencyInjection包,而後直接在Web層測試怎麼用AutoMapper,學會後我想把Profile放到Service層後,而後在Service層上安裝AutoMapper包,而後按F6生成解決方案後,發現依賴包就自動消失了,弄了很久次,一按F6,AutoMapper包就自動消失,我一直搞不懂爲何,而後我把整個解決方案裏AutoMapper相關的代碼跟依賴包都刪了,而後再安裝個AutoMapper跟AutoMapper.Extensions.Microsoft.DependencyInjection,就正常了,後面我想重現以前的問題,但發現我怎麼裝都正常了,這是個很奇怪的問題,我也搞不懂爲何。app
如下是個人解決方案目錄,第一個紅圈是Web層,第二個紅圈是Service層,我把映射的Profile放在Service層的AutoMapper目錄,由於我以爲映射就是Service該乾的活框架
這是實體類SysUser,我放在了Entity層前後端分離
public class SysUser { [Key] public int Id { get; set; } public string LoginName { get; set; } public string Name { get; set; } }
這是SysUser對應的DTO類SysUserDTO,我放在了DTO層,注意那個TestName字段,是我等下用來演示用的ide
public class SysUserDTO { public int Id { get; set; } public string LoginName { get; set; } public string Name { get; set; } public string TestName { get; set; } }
而後我在Service裏建立一個文件夾AutoMapper,建立一個MapperProfile.cs類,記得安裝AutoMapper包函數
MapperProfile.cs,我目前是把全部實體跟DTO的映射都寫在一個Profile類中,就是建立不少個CreateMappost
using AutoMapper; using System; using System.Collections.Generic; using System.Text; using ItSys.Entity; using ItSys.DTO; namespace ItSys.Service.AutoMapper { public class MapperProfile : Profile { public MapperProfile() { //建立SysUser往SysUserDTO轉換的映射,ReverseMap是建立反向映射,不過我發現若是都是同名的屬性的話,沒加這個ReverseMap也是能反向映射的 CreateMap<SysUser, SysUserDTO>().ReverseMap(); } } }
而後在Web層的Startup.cs類裏的ConfigureServices方法裏AddAutoMapper(記得安裝AutoMapper.Extensions.Microsoft.DependencyInjection包),這個方法會自動找到全部繼承了Profile類的配置類進行映射配置測試
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddAutoMapper(); }
注意這個方法若是像我上面這樣寫的話,就會獲取全部引用的程序集裏全部繼承了Profile類的派生類進行配置,因此我即便Profile放在Service層裏也是能獲取到的,固然你也能夠傳入一個程序集參數,例如這樣:AddAutoMapper(Assembly.GetAssembly(typeof(BaseService<>))),或者傳入一個類AddAutoMapper(typeof(BaseService<>)),那AutoMapper就只會在程序集或類的程序集範圍內查找了。this
而後我在SysUserService類裏就能夠這樣寫了,注意紅色的代碼
using System; using System.Collections.Generic; using System.Text; using ItSys.DTO; using ItSys.Repository.Sys; using ItSys.Entity; using AutoMapper; namespace ItSys.Service.Sys { public class SysUserService : BaseService<SysUser> { private IMapper _mapper; protected SysUserRepository repository; public SysUserService(SysUserRepository repository,IMapper mapper) { base.baseRepository = repository; this.repository = repository; _mapper = mapper; } public virtual SysUserDTO GetById(int id) { var sysUserEntity = repository.GetById(id); if (sysUserEntity == null) { throw new Exception("沒找到數據"); } return _mapper.Map<SysUserDTO>(sysUserEntity); } } }
因此AutoMapper使用起來就是這麼簡單的。
對了,關於那個SysUserDTO的TestName字段,若是我想這個字段等於SysUser的LoginName跟Name字段相連的字符串,怎麼弄的,很簡單,在那個MapperProfile類中這麼寫
using AutoMapper; using System; using System.Collections.Generic; using System.Text; using ItSys.Entity; using ItSys.DTO; namespace ItSys.Service.AutoMapper { public class MapperProfile : Profile { public MapperProfile() { //建立SysUser往SysUserDTO轉換的映射,ReverseMap是建立反向映射,若是都是同名的屬性的話,沒加這個ReverseMap也是能反向映射的,不過像如下這個有特殊屬性的,就得加ReverseMap才能正常反向映射 CreateMap<SysUser, SysUserDTO>() .ForMember(destinationObject => destinationObject.TestName, options => { //目標類的TestName等於實體類的LoginName加上Name字段 options.MapFrom(sourceObject => sourceObject.LoginName + sourceObject.Name); }) .ReverseMap(); } } }