此文介绍
AutoMapper
和Mapster
的简单使用和配置
两者都用于 : 自动映射 实体Entity
与 视图DTO
四步骤:
Program
中注册配置文件AutoMapper
Extension
拓展类库 添加配置文件namespace WebProject.Extension;
///
/// 静态全局 AutoMapper 配置文件
///
public class AutoMapperConfig
{
public static MapperConfiguration RegisterMappings()
{
// 引入自定义配置信息文件CustomProfile
return new MapperConfiguration(cfg => { cfg.AddProfile(new CustomProfile()); });
}
}
Profile
Profile
类namespace WebProject.Extension;
public class CustomProfile : Profile
{
///
/// 配置构造函数,用来创建关系映射
///
public CustomProfile()
{
// 实体内部属性名字如果都一样就直接将类关联
CreateMap<User, UserDto>();
// 实体内部属性命名不同或有特殊的设置,需要将属性字段一一对应
CreateMap<Role, RoleDto>()
.ForMember(d => d.Name,
opt => opt.MapFrom(src => src.RoleName));
}
}
Program
注册// 配置注册AutoMapper
builder.Services.AddAutoMapper(typeof(AutoMapperConfig));
AutoMapperConfig.RegisterMappings();
_mapper.Map>(Entity)
_mapper.Map(来源)
public class TestServices : ITestService
{
private ITestRepository _testRepository; // 仓储层 与数据库关联的层级
private readonly IMapper _mapper; // 添加AutoMapper依赖注入
// 这里使用构造注入
public TestServices(ITestRepository testRepository, IMapper mapper)
{
_testRepository = testRepository;
_mapper = mapper;
}
// 查询方法 返回 List 数据
// 这里需要将实体Entity 转换成 Dto 返回给Controller层提供给前端
public async Task<List<UserDto>> Query()
{
var entities = await _testRepository.Query(); //获取到实体Entity对象
return _mapper.Map<List<UserDto>>(entities); // 使用
}
}
同样四步骤:
添加Mapster
依赖 Nuget下载,同样类库项目放在Service层
其实如果 属性字段命名相同,配置文件都不用写,导入完依赖,在Service层使用
Adapt<>
方法直接 就可以自动映射实体与视图
举例 :
// 当实体名字对应 不用再写自定义配置文件(:Profile) 直接用
// var 目标 = 来源.Adapt<目标>();
var userDto = userEntity.Adapt<UserDto>();
// Entity.Adapt();
当命名不同时:
namespace ProjectWebApi.Common.Mapster;
///
/// 实现Mapster的IRegister自动映射
///
public static class ImplAutoIRegisterExtensions
{
///
/// 添加对象映射
///
/// 服务集合
/// 扫描的程序集
public static IServiceCollection AddMapsterIRegister(this IServiceCollection services, params Assembly[] assemblies)
{
// 获取全局映射配置
var config = TypeAdapterConfig.GlobalSettings;
// 扫描所有继承 IRegister 接口的对象映射配置
if (assemblies != null && assemblies.Length > 0) config.Scan(assemblies);
// 配置默认全局映射(支持覆盖)
config.Default
.NameMatchingStrategy(NameMatchingStrategy.Flexible)
.PreserveReference(true);
// 配置默认全局映射(忽略大小写敏感)
config.Default
.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase)
.PreserveReference(true);
// 配置支持依赖注入
services.AddSingleton(config);
return services;
}
}
IRegister
( 因为配置文件 会自动检索程序集 找出有实现这个接口的类 )
IRegister
接口使用namespace DougWebApi.Common.Mapster;
public class MyTypeAdapterConfig : IRegister
{
public void Register(TypeAdapterConfig config)
{
// 简单映射
config.ForType<User, UserDto>().Map(dest => dest.NickName, src => src.Name);
// 复杂映射
config.ForType<Employee, EmployeeDto>()
.Map(dest => dest.Name,
src => $"{src.FirstName}{src.LastName}")
.Map(dest => dest.GenderDisplay, src => src.Gender.ToString())
.Map(dest => dest.Age, src => DateTime.Now.Year - src.DateOfBirth.Year);
}
}
Program
注册// 捕获当前运行时的程序集 (不会捕获其他的类库,只有主项目)
builder.Services.AddMapsterIRegister(Assembly.GetExecutingAssembly());
// 或者使用 : (得到所有已加载的程序集,而不仅仅是当前的程序集)
builder.Services.AddMapsterIRegister(AppDomain.CurrentDomain.GetAssemblies());
// 再或者 加载 单个指定的程序集(自定义配置项文件存在的类库项目的程序集加载)
// MyTypeAdapterConfig : IRegister 扫描接口
builder.Services.AddMapsterIRegister(Assembly.LoadFrom(Path.Combine(AppContext.BaseDirectory, "XX.Common.dll")));
var 目标 = 来源.Adapt<目标>();
推荐使用 Mapster
导入组件使用 基本都是 四步骤(or 三步骤肯定 :
C# Mapster 对象映射器(C#对象映射器) - 一颗花生豆 - 博客园 ↩︎
Mapster配置文件写法参考 ↩︎