aspnet-core-mappers-automapper-mapster-benchmark

Mapeo de objetos en .NET: AutoMapper, Mapster o manual

  • 4 min

Un mapper de objetos es una herramienta para convertir objetos de un tipo en objetos de otro tipo.

Si has seguido los artículos anteriores sobre DTOs, te habrás encontrado con una tarea repetitiva y aburrida.

Tienes tu entidad Usuario con 20 propiedades, y tu UsuarioDto con las mismas 20 propiedades. Y te toca escribir esto:

var dto = new UsuarioDto
{
    Nombre = usuario.Nombre,
    Apellido = usuario.Apellido,
    Email = usuario.Email,
    // ... y así 17 líneas más ...
};
Copied!

Esto es código repetitivo. Es fácil olvidar una propiedad y, cuando hay muchos mapeos, termina ensuciando los servicios.

Los mappers de objetos automatizan parte de ese trabajo mediante convenciones, expresiones compiladas o generación de código.

Vamos a comparar dos alternativas habituales: AutoMapper y Mapster.

AutoMapper

AutoMapper es una biblioteca veterana y muy extendida en el ecosistema .NET.

Cómo funciona

AutoMapper funciona basándose en Perfiles. Debes decirle explícitamente qué clases se pueden mapear entre sí.

Instalación

dotnet add package AutoMapper
Copied!

Configuración del perfil

Creamos una clase que herede de Profile. Aquí definimos las reglas.

using AutoMapper;

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        // Mapeo simple: Propiedades con mismo nombre se copian solas
        CreateMap<Producto, ProductoDto>();

        // Mapeo inverso (de DTO a Entidad)
        CreateMap<CrearProductoDto, Producto>();

        // Mapeo personalizado: Si los nombres no coinciden
        CreateMap<Usuario, UsuarioDto>()
            .ForMember(dest => dest.NombreCompleto,
                       opt => opt.MapFrom(src => $"{src.Nombre} {src.Apellido}"));
    }
}
Copied!

Registro e inyección

En Program.cs, registramos el servicio indicando un tipo de la assembly donde están los perfiles.

builder.Services.AddAutoMapper(
    cfg => cfg.LicenseKey = "<license-key>",
    typeof(MappingProfile));
Copied!

Desde AutoMapper 13, AddAutoMapper forma parte del paquete principal AutoMapper. El paquete antiguo AutoMapper.Extensions.Microsoft.DependencyInjection quedó discontinuado. AutoMapper 15 requiere revisar su licencia y configurar una clave; también puede descubrirla mediante la variable AUTOMAPPER_LICENSE_KEY.

Uso

Inyectamos IMapper en nuestro servicio o controlador.

public class ProductoService
{
    private readonly IMapper _mapper;

    public ProductoService(IMapper mapper)
    {
        _mapper = mapper;
    }

    public ProductoDto Get(int id)
    {
        var entidad = _repo.Get(id);

        // Convierte entidad a DTO
        return _mapper.Map<ProductoDto>(entidad);
    }
}
Copied!

Mapster

En los últimos años, Mapster ha ganado popularidad como alternativa con una API sencilla y opciones de generación de código.

Mapster puede adaptar objetos en tiempo de ejecución y también ofrece generación de código en compilación. Si el rendimiento importa, conviene medir el caso real en lugar de elegir solo por un benchmark genérico.

Cómo funciona

Mapster apuesta por la convención sobre la configuración. A menudo no necesitas configurar nada.

Instalación

dotnet add package Mapster
Copied!

Uso directo

No necesitas inyectar nada si no quieres. Mapster añade métodos de extensión a todos tus objetos.

using Mapster;

public ProductoDto Get(int id)
{
    var entidad = _repo.Get(id);

    // Método de extensión .Adapt<T>()
    var dto = entidad.Adapt<ProductoDto>();

    return dto;
}
Copied!

Configuración global

Si necesitas mapeos personalizados, puedes configurarlos al inicio de la app:

TypeAdapterConfig<Usuario, UsuarioDto>
    .NewConfig()
    .Map(dest => dest.NombreCompleto, src => src.Nombre + " " + src.Apellido);
Copied!

AutoMapper y Mapster

CaracterísticaAutoMapperMapster
Configuración habitualPerfiles y IMapperConvenciones, configuración global o código generado
UsoInyección de IMapperMétodos de extensión como Adapt o servicios configurados
Proyección de consultasProjectToProjectToType
LicenciaRequiere revisar la licencia desde la versión 15MIT

Mapeo manual

También podemos no usar ninguna librería y escribir métodos de mapeo explícitos.

Escribir tus propios métodos de extensión .ToDto() es repetitivo, pero tiene ventajas claras:

  1. Rendimiento predecible: Una asignación directa evita el coste del mapeador.
  2. Referencias: Puedes hacer “Click derecho -> Buscar referencias” en una propiedad y saber exactamente dónde se está usando. Con AutoMapper, esa relación queda oculta al IDE.
  3. Depuración: Si falla el mapeo, pones un breakpoint y lo ves.
// Mapeo manual con métodos de extensión
public static class ProductoMappers
{
    public static ProductoDto ToDto(this Producto entidad)
    {
        return new ProductoDto(entidad.Id, entidad.Nombre, entidad.Precio);
    }
}

// Uso
return entidad.ToDto();
Copied!