【.Net】对象映射器 AutoMapper VS Mapster

前言

此文介绍 AutoMapperMapster 的简单使用和配置

两者都用于 : 自动映射 实体Entity 与 视图DTO

AutoMapper

四步骤:

  1. 导入依赖
  2. 创建配置文件
  3. 创建自定义映射文件
  4. Program中注册配置文件

1. 导入依赖

  • Nuget包
    • ( 类库项目可在Service层导入 )
AutoMapper.Extensions.Microsoft.DependencyInjection

2. 创建配置文件

  • 项目 中 可创建一个Extension拓展类库 添加配置文件
namespace WebProject.Extension;
/// <summary>
/// 静态全局 AutoMapper 配置文件
/// </summary>
public class AutoMapperConfig
{
    public static MapperConfiguration RegisterMappings()
    {
    	// 引入自定义配置信息文件CustomProfile
        return new MapperConfiguration(cfg => { cfg.AddProfile(new CustomProfile()); });
    }
}

3. 创建自定义配置信息文件 Profile

  • 自定义文件 继承Profile
namespace WebProject.Extension;
public class CustomProfile : Profile
{
    /// <summary>
    /// 配置构造函数,用来创建关系映射
    /// </summary>
    public CustomProfile()
    {
        // 实体内部属性名字如果都一样就直接将类关联
        CreateMap<User, UserDto>();
        // 实体内部属性命名不同或有特殊的设置,需要将属性字段一一对应
        CreateMap<Role, RoleDto>()
        .ForMember(d => d.Name, 
        			opt => opt.MapFrom(src => src.RoleName));
    }
}

4. Program注册

// 配置注册AutoMapper
builder.Services.AddAutoMapper(typeof(AutoMapperConfig));
AutoMapperConfig.RegisterMappings();

使用

  • 在Service层 进行视图模型Dto与实体Entity的绑定
  • _mapper.Map<List<XXDto>>(Entity)
    • _mapper.Map<List<目标>(来源)
    public class TestServices : ITestService
    {
        private ITestRepository _testRepository; // 仓储层 与数据库关联的层级
        private readonly IMapper _mapper; // 添加AutoMapper依赖注入

		// 这里使用构造注入
        public TestServices(ITestRepository testRepository, IMapper mapper)
        {
            _testRepository = testRepository;
            _mapper = mapper;
        }
		
		// 查询方法 返回 List<UserDto> 数据
		// 这里需要将实体Entity 转换成 Dto 返回给Controller层提供给前端
        public async Task<List<UserDto>> Query()
        {
            var entities = await _testRepository.Query(); //获取到实体Entity对象
            return _mapper.Map<List<UserDto>>(entities); // 使用
        }
    }

Mapster1

同样四步骤:

  1. 导入依赖
  2. 创建配置文件
  3. 自定义映射规则
  4. 注册配置文件

1. 导入依赖

添加Mapster依赖 Nuget下载,同样类库项目放在Service层

其实如果 属性字段命名相同,配置文件都不用写,导入完依赖,在Service层使用Adapt<>方法直接 就可以自动映射实体与视图

举例 :

// 当实体名字对应 不用再写自定义配置文件(:Profile) 直接用
// var 目标 = 来源.Adapt<目标>();
 var userDto = userEntity.Adapt<UserDto>(); 
// Entity.Adapt<Dto>(); 

2. 创建配置文件

当命名不同时:

  • 以下为自动配置 2工具类 ,直接用
namespace ProjectWebApi.Common.Mapster;

/// <summary>
/// 实现Mapster的IRegister自动映射
/// </summary>
public static class ImplAutoIRegisterExtensions
{
    /// <summary>
    /// 添加对象映射
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="assemblies">扫描的程序集</param>
    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;
    }
}

3. 自定义

  • 自定义配置项
    • 需要 实现 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);
    }
}

4. 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 三步骤肯定 :

  1. 依赖
  2. 配置组件
  3. 自定义文件( 这条有的组件不用
  4. 注册

拓展

参考


  1. C# Mapster 对象映射器(C#对象映射器) - 一颗花生豆 - 博客园 ↩︎

  2. Mapster配置文件写法参考 ↩︎

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值