AutoMapper 可以很方便完成數據對象之間的轉換。
Dto -> Entity
Entity -> ViewModel
Step 1:通過 NuGet 安裝 AutoMapper 的包。

<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="AutoMapper" Version="9.0.0" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" /> </ItemGroup> </Project>
准備兩個類 User 和 Department

public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Remark { get; set; } public int DepartmentId { get; set; } public Department DepartmentInfo { get; set; } }

public class Department { public int Id { get; set; } public string Name { get; set; } public string Remark { get; set; } }
創建 User 的 Dto 和 ViewModel

public class UserDto { public int Id { get; set; } public string Name { get; set; } }

public class UserViewModel { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Remark { get; set; } public int DepartmentId { get; set; } public string DepartmentName { get; set; } }
Step 2:配置好對象之間的轉換。
創建類 UserMapper 繼承抽象類 Profile

public class UserMapper : Profile { public UserMapper() { CreateMap<UserDto, User>(); CreateMap<User, UserViewModel>() .BeforeMap((u, v) => u.Remark = "Good") .ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId)) .ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name)) .AfterMap((u, v) => u.Age++); } }
Profile 里面實現了兩個接口
Step 3:注冊服務
在 Startup.cs 的 ConfigureServices 方法中注冊。

public void ConfigureServices(IServiceCollection services) { // ... services.AddAutoMapper(typeof(UserMapper)); // ... }
Step 4:使用
創建 api 控制器
聲明 private readonly IMapper _mapper;

[Route("api/[controller]/[action]")] [ApiController] public class UserController : ControllerBase { private readonly IMapper _mapper; public UserController(IMapper mapper) { _mapper = mapper; } [ActionName("dto")] [HttpGet] public IActionResult DtoToEntity() { var userDto = new UserDto() { Id = 1, Name = "Bill" }; var userEntity = _mapper.Map<UserDto, User>(userDto); JsonResult result = new JsonResult(userEntity); return result; } [ActionName("vo")] [HttpGet] public IActionResult EntityToViewModel() { var department = new Department() { Id = 101, Name = "Market" }; var user = new User() { Id = 1, Name = "Bill", Age = 25, DepartmentId = 101, DepartmentInfo = department }; var viewModel = _mapper.Map<User, UserViewModel>(user); JsonResult result = new JsonResult(viewModel); return result; } }
結果:
Dto -> Entity
Entity -> ViewModel
Step 5:自動化注冊
如果每添加一個 Mapper 都需要修改 StartUp 類來完成注冊,不是什么好方式。
自動化注冊才是更好的(主要還是方便摸魚)。
為了實現自動化注冊,需要找到項目中的所有 Mapper 對象,要給 Mapper 打上一個標記。
添加接口類 IProfile

public interface IProfile { }
在所有的 Mapper 類里面,實現這個接口。

public class UserMapper : Profile, IProfile { public UserMapper() { CreateMap<UserDto, User>(); CreateMap<User, UserViewModel>() .BeforeMap((u, v) => u.Remark = "Good") .ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId)) .ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name)) .AfterMap((u, v) => u.Age++); } }
再通過查找所有實現了 IProfile 接口的類,就可以找到所有的 Mapper 對象。
( Profile 是 AutoMapper 組件里的接口,必須自定義項目中的唯一標記。)
創建 MapperRegister 類,實現獲取所有的 Mapper 對象。

public class MapperRegister { /// <summary> /// 通過反射自動化注冊 /// </summary> /// <returns></returns> public static Type[] MapType() { Assembly ass = Assembly.GetAssembly(typeof(IProfile)); Type[] types = ass.GetTypes(); List<Type> allList = new List<Type>(); foreach (Type item in types) { if (item.IsInterface) continue;//判斷是否是接口 Type[] ins = item.GetInterfaces(); foreach (Type ty in ins) { if (ty == typeof(IProfile)) { allList.Add(item); } } } Type[] alltypes = allList.ToArray(); return alltypes; } }
修改 StrartUp 類,調整注冊方式。

public void ConfigureServices(IServiceCollection services) { services.AddControllers(); //services.AddAutoMapper(typeof(UserMapper)); //自動化注冊 services.AddAutoMapper(MapperRegister.MapType()); }
這樣就可以每次添加 Mapper 類的時候,只需要添加 IProfile 標記,就可以自動注冊了。
自動化注冊方式二:
在很多常見的項目中,同一個項目的Mapper文件都是放在同一個文件夾內。命名都以 Mapper 結尾。
然后在 Startup.cs 里面
services.AddAutoMapper( Assembly.Load("Leaf.Application").GetTypes() .Where(t => t.FullName.EndsWith("Mapper")) .ToArray() );