摘要:致力于挖掘功能强大、性能优越、创新前沿且简单易用的 C#/.NET 开源框架、项目、类库与工具。助力 .NET 开发者轻松解锁并运用这些实用的宝藏资源,提升开发效率与创新能力!
致力于挖掘功能强大、性能优越、创新前沿且简单易用的 C#/.NET 开源框架、项目、类库与工具。助力 .NET 开发者轻松解锁并运用这些实用的宝藏资源,提升开发效率与创新能力!
作为在 .NET 生态中深耕多年的开发者,我们对对象映射(Object Mapping)的需求从未减弱。长期以来,AutoMapper一直是社区的首选工具,以其简洁的配置和强大的功能赢得了无数开发者的青睐。
然而,一个重大变化正在发生:AutoMapper 已宣布转向收费模式。这对于许多个人开发者、初创团队以及预算有限的项目来说,无疑是一个巨大的冲击。
好消息是,我们有一个强大、高效且完全免费开源的替代方案——Mapster。
Mapster 不仅在性能上显著优于 AutoMapper(基准测试显示其速度通常是 AutoMapper 的 5-10 倍),而且提供了更直观的 API、更少的配置开销和更灵活的映射选项。它支持 .NET Framework 和 .NET Core/.NET 5+,是现代 .NET 应用的理想选择。
Mapster开源地址:https://github.com/MapsterMapper/Mapster
使用 NuGet 包管理器安装 Mapster 及其依赖。
# 核心库Install-Package Mapster
# (推荐) 如果你使用 ASP.NET Core,安装此包以获得更好的集成
Install-Package Mapster.DependencyInjection
或者使用 .NET CLI:
dotnet add package Mapsterdotnet add package Mapster.DependencyInjection
// 源对象
publicclassUserDto
{
publicint Id { get; set; }
publicstring FirstName { get; set; }
publicstring LastName { get; set; }
publicstring Email { get; set; }
public DateTime DateOfBirth { get; set; }
}
// 目标对象
publicclassUserModel
{
publicstring FullName { get; set; }
publicstring EmailAddress { get; set; }
publicint Age { get; set; }
}
零配置映射
Mapster 的一大优势是约定优于配置。对于名称相同、类型兼容的属性,Mapster 可以自动映射。
var userDto = new UserDto{
Id = 1,
FirstName = "John",
LastName = "Doe",
Email = "john.doe@email.com",
DateOfBirth = new DateTime(1990, 5, 15)
};
// 零配置映射(仅映射 Id 和 Email)
var userModel = userDto.Adapt
// 结果: Id=1, FullName=null, EmailAddress=null, Age=0
注意:FirstName、LastName、DateOfBirth没有被映射,因为目标对象中没有同名属性。配置映射规则我们需要告诉 Mapster 如何处理FullName、EmailAddress和Age。using Mapster;
// 在应用启动时(如 Program.cs 或 Startup.cs)配置映射
TypeAdapterConfig
.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// 结果: Id=1, FullName="John Doe", EmailAddress="john.doe@email.com", Age=35
完美!Mapster 自动处理了Id,并根据我们的配置生成了FullName、EmailAddress和Age。忽略特定属性TypeAdapterConfig
.Ignore(dest => dest.Age) // 忽略 Age 属性
.Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}");
条件映射TypeAdapterConfig
.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 Listvar userModelList = userDtos.Adapt
// 或者
var userModelArray = userDtos.Adapt
反向映射// 配置反向映射
TypeAdapterConfig
.Map(dest => dest.FullName, src => $"{src.FirstName} {src.LastName}")
.Reverse; // 启用反向映射
// 现在可以反向映射
var userModel = new UserModel { FullName = "Jane Smith" };
var userDto = userModel.Adapt
使用Mapster.DependencyInjection包简化集成。// Program.cs (.NET 6+)
var builder = WebApplication.CreateBuilder(args);
// 添加 Mapster 服务
builder.Services.AddMapster;
var app = builder.Build;
// 配置映射(可以放在单独的配置类中)
TypeAdapterConfig
.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
return Ok(userModel);
}
}
AutoMapper
Mapster
CreateMapTypeAdapterConfig.ForMember(dest => dest.Prop, opt => opt.MapFrom(src => src.SrcProp)).Map(dest => dest.Prop, src => src.SrcProp).Ignore.Ignore(dest => dest.Prop)ReverseMap.Reversemapper.Mapsrc.Adapt或src.ProjectToType(EF)Mapster 不仅是 AutoMapper 的一个优秀替代品,更是一个在性能和易用性上都更胜一筹的现代映射库。面对 AutoMapper 的收费转型,现在是拥抱 Mapster 的最佳时机。
来源:opendotnet