大数跨境
0
0

AutoMapper 收费了,.NET 开发者速来拥抱 Mapster,现代免费的对象映射库!

AutoMapper 收费了,.NET 开发者速来拥抱 Mapster,现代免费的对象映射库! DotNet项目宝库
2025-09-25
0
导读:作为在 .NET 生态中深耕多年的开发者,我们对对象映射(Object Mapping)的需求从未减弱。长期以来,AutoMapper 一直是社区的首选工具,以其简洁的配置和强大的功能赢得了无数开发者

致力于挖掘功能强大、性能优越、创新前沿且简单易用的 C#/.NET 开源框架、项目、类库与工具。助力 .NET 开发者轻松解锁并运用这些实用的宝藏资源,提升开发效率与创新能力!

前言

作为在 .NET 生态中深耕多年的开发者,我们对对象映射(Object Mapping)的需求从未减弱。长期以来,AutoMapper 一直是社区的首选工具,以其简洁的配置和强大的功能赢得了无数开发者的青睐。

然而,一个重大变化正在发生:AutoMapper 已宣布转向收费模式。这对于许多个人开发者、初创团队以及预算有限的项目来说,无疑是一个巨大的冲击。

好消息是,我们有一个强大、高效且完全免费开源的替代方案——Mapster

为什么选择 Mapster?

Mapster 不仅在性能上显著优于 AutoMapper(基准测试显示其速度通常是 AutoMapper 的 5-10 倍),而且提供了更直观的 API、更少的配置开销和更灵活的映射选项。它支持 .NET Framework 和 .NET Core/.NET 5+,是现代 .NET 应用的理想选择。

  • Mapster开源地址:https://github.com/MapsterMapper/Mapster

第一步:安装 Mapster

使用 NuGet 包管理器安装 Mapster 及其依赖。

# 核心库
Install-Package Mapster

# (推荐) 如果你使用 ASP.NET Core,安装此包以获得更好的集成
Install-Package Mapster.DependencyInjection

或者使用 .NET CLI:

dotnet add package Mapster
dotnet add package Mapster.DependencyInjection

第二步:基础映射 - 从零开始

假设我们有以下两个简单的 DTO 类:

// 源对象
publicclassUserDto
{
    publicint Id { getset; }
    publicstring FirstName { getset; }
    publicstring LastName { getset; }
    publicstring Email { getset; }
    public DateTime DateOfBirth { getset; }
}

// 目标对象
publicclassUserModel
{
    publicint Id { getset; }
    publicstring FullName { getset; }
    publicstring EmailAddress { getset; }
    publicint Age { getset; }
}

零配置映射

Mapster 的一大优势是约定优于配置。对于名称相同、类型兼容的属性,Mapster 可以自动映射。

var userDto = new UserDto
{
    Id = 1,
    FirstName = "John",
    LastName = "Doe",
    Email = "john.doe@email.com",
    DateOfBirth = new DateTime(1990515)
};

// 零配置映射(仅映射 Id 和 Email)
var userModel = userDto.Adapt<UserModel>();
// 结果: Id=1, FullName=null, EmailAddress=null, Age=0

注意:FirstNameLastNameDateOfBirth 没有被映射,因为目标对象中没有同名属性。

配置映射规则

我们需要告诉 Mapster 如何处理 FullNameEmailAddress 和 Age

using Mapster;

// 在应用启动时(如 Program.cs 或 Startup.cs)配置映射
TypeAdapterConfig<UserDto, UserModel>.NewConfig()
    .Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}")
    .Map(dest => dest.EmailAddress, src => src.Email)
    .Map(dest => dest.Age, src => DateTime.Now.Year - src.DateOfBirth.Year);

现在,再次映射:

var userModel = userDto.Adapt<UserModel>();
// 结果: Id=1, FullName="John Doe", EmailAddress="john.doe@email.com", Age=35

完美!Mapster 自动处理了 Id,并根据我们的配置生成了 FullNameEmailAddress 和 Age

第三步:高级映射技巧

忽略特定属性

TypeAdapterConfig<UserDto, UserModel>.NewConfig()
    .Ignore(dest => dest.Age) // 忽略 Age 属性
    .Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}");

条件映射

TypeAdapterConfig<UserDto, UserModel>.NewConfig()
    .Map(dest => dest.EmailAddress, src => src.Email, 
         src => !string.IsNullOrEmpty(src.Email)); // 仅当 Email 不为空时映射

全局配置

你可以设置全局行为,避免重复配置。

TypeAdapterConfig.GlobalSettings.Default
    .NameMatchingStrategy(NameMatchingStrategy.Flexible) // 灵活的名称匹配
    .PreserveReference(true); // 处理循环引用

映射集合

Mapster 对集合映射有极佳支持。

var userDtos = new List<UserDto> { userDto1, userDto2 };
var userModelList = userDtos.Adapt<List<UserModel>>();
// 或者
var userModelArray = userDtos.Adapt<UserModel[]>();

反向映射

// 配置反向映射
TypeAdapterConfig<UserDto, UserModel>.NewConfig()
    .Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}")
    .Reverse(); // 启用反向映射

// 现在可以反向映射
var userModel = new UserModel { FullName = "Jane Smith" };
var userDto = userModel.Adapt<UserDto>(); // FirstName="Jane", LastName="Smith"

第四步:在 ASP.NET Core 中集成

使用 Mapster.DependencyInjection 包简化集成。

// Program.cs (.NET 6+)
var builder = WebApplication.CreateBuilder(args);

// 添加 Mapster 服务
builder.Services.AddMapster();

var app = builder.Build();

// 配置映射(可以放在单独的配置类中)
TypeAdapterConfig<UserDto, UserModel>.NewConfig()
    .Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}")
    .Map(dest => dest.EmailAddress, src => src.Email);

在控制器中注入 IAdapter

[ApiController]
[Route("api/[controller]")]
publicclassUsersController : ControllerBase
{
    privatereadonly IAdapter _adapter;

    public UsersController(IAdapter adapter)
    {
        _adapter = adapter;
    }

    [HttpGet("{id}")]
    public IActionResult GetUser(int id)
    {
        var userDto = _userService.GetUser(id);
        var userModel = _adapter.Adapt<UserModel>(userDto);
        return Ok(userModel);
    }
}

第五步:性能优化建议

  • 预编译映射:Mapster 支持预编译映射表达式,避免运行时反射开销。

    TypeAdapterConfig<UserDto, UserModel>.NewConfig()
        .Compile(); // 预编译
  • 避免在热路径中配置:所有配置应在应用启动时完成。

  • 使用 Adapt<T> 扩展方法:这是最高效的 API。

迁移指南:从 AutoMapper 到 Mapster

AutoMapper
Mapster
CreateMap<Source, Dest>() TypeAdapterConfig<Source, Dest>.NewConfig()
.ForMember(dest => dest.Prop, opt => opt.MapFrom(src => src.SrcProp)) .Map(dest => dest.Prop, src => src.SrcProp)
.Ignore() .Ignore(dest => dest.Prop)
ReverseMap() .Reverse()
mapper.Map<Dest>(src) src.Adapt<Dest>()
 或 src.ProjectToType<Dest>() (EF)

结论

Mapster 不仅是 AutoMapper 的一个优秀替代品,更是一个在性能和易用性上都更胜一筹的现代映射库。面对 AutoMapper 的收费转型,现在是拥抱 Mapster 的最佳时机。

图片



图片

【声明】内容源于网络
0
0
DotNet项目宝库
致力于挖掘功能强大、性能优越、创新前沿且简单易用的 C#/.NET 开源框架、项目、类库与工具。助力 .NET 开发者轻松解锁并运用这些实用的宝藏资源,提升开发效率与创新能力!
内容 86
粉丝 0
DotNet项目宝库 致力于挖掘功能强大、性能优越、创新前沿且简单易用的 C#/.NET 开源框架、项目、类库与工具。助力 .NET 开发者轻松解锁并运用这些实用的宝藏资源,提升开发效率与创新能力!
总阅读16
粉丝0
内容86