AutoMapper 可以很方便完成数据对象之间的转换。
Dto -> Entity
Entity -> ViewModel
Step 1:通过 NuGet 安装 AutoMapper 的包。
Project.csproj
准备两个类 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; }
}
User
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public string Remark { get; set; }
}
Department
创建 User 的 Dto 和 ViewModel
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
}
UserDto
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; }
}
UserViewModel
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++);
}
}
UserMapper
Profile 里面实现了两个接口
Step 3:注册服务
在 Startup.cs 的 ConfigureServices 方法中注册。
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAutoMapper(typeof(UserMapper));
// ...
}
ConfigureServices
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;
}
}
UserController
结果:
Dto -> Entity
Entity -> ViewModel
Step 5:自动化注册
如果每添加一个 Mapper 都需要修改 StartUp 类来完成注册,不是什么好方式。
自动化注册才是更好的(主要还是方便摸鱼)。
为了实现自动化注册,需要找到项目中的所有 Mapper 对象,要给 Mapper 打上一个标记。
添加接口类 IProfile
public interface IProfile
{
}
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++);
}
}
UserMapper
再通过查找所有实现了 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;
}
}
MapperRegister
修改 StrartUp 类,调整注册方式。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//services.AddAutoMapper(typeof(UserMapper));
//自动化注册
services.AddAutoMapper(MapperRegister.MapType());
}
Startup
这样就可以每次添加 Mapper 类的时候,只需要添加 IProfile 标记,就可以自动注册了。
自动化注册方式二:
在很多常见的项目中,同一个项目的Mapper文件都是放在同一个文件夹内。命名都以 Mapper 结尾。
然后在 Startup.cs 里面
services.AddAutoMapper(
Assembly.Load("Leaf.Application").GetTypes()
.Where(t => t.FullName.EndsWith("Mapper"))
.ToArray()
);
Assembly.Load() 里面传的是当前项目的名称,或者类库的名称。获取当前项目下的所有类文件。
通过 Lamda 表达式 Where 找到所有以 Mapper 结尾的文件。
这样就可以自动注册项目内的所有 Mapper 文件了。
摸鱼又更进了一步。
AutoMapper 配合强类型字段的 ORM 特别好用。比如 EF 。
入参控制好 Add 的 Dto。
返回参数 控制好 ViewModel。
这些文件都可以从数据库 Entity 对象里面复制,不需要手写字段。
无论多长的字段,都可以通过 Ctrl + C 和 Ctrl + V 来创建对应的 Dto 和 ViewModel 。
再通过 AutoMapper 的转换。
做 CURD 接口的时候,不需要写任何 Entity 里已存在的字段。
然后就可以愉快地上班摸鱼了。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章