DEV Community

Bruno Silva
Bruno Silva

Posted on

Migrando do AutoMapper para Mapster em .NET: Segurança, Performance e Custo Zero

Fala, pessoal! 👋

Hoje o papo é sobre uma mudança que muitos times estão enfrentando: a substituição do tradicional AutoMapper, por outro pacote, aqui e eu optei pelo Mapster e vou contar como foi o processo de migração, por que decidimos sair do AutoMapper e como o Mapster pode ser um aliado para manter sua aplicação rápida, segura e, o melhor, sem custos adicionais. Bora conferir? 😉

O Cenário: Por que mudar?

O AutoMapper sempre foi o padrão de mercado, mas o cenário mudou drasticamente por dois motivos principais:

  1. Vulnerabilidade Crítica: A versão 13 (gratuita) do AutoMapper apresenta vulnerabilidades conhecidas que podem comprometer a segurança da aplicação.

  2. Mudança de Licenciamento: As novas versões corrigidas e estáveis do AutoMapper passaram a adotar um modelo pago, o que pode inviabilizar a migração para muitos projetos e empresas.

Diante disso, precisávamos de uma alternativa que fosse open-source (MIT), mantivesse a produtividade do time e, se possível, trouxesse ganhos de performance. Foi aí que o Mapster entrou em cena. 🚀

Por que Mapster?

O Mapster não é apenas um "substituto", ele é uma evolução em vários aspectos:

  • ✅ Performance Extrema: Ele gera código otimizado em tempo de execução (JIT) ou compilação, sendo significativamente mais rápido que o AutoMapper.
  • ✅ Memória Otimizada: Consome menos recursos, o que é vital para microsserviços e APIs de alta escala.
  • ✅ Sintaxe Familiar: Se você já usa AutoMapper, vai se sentir em casa. A curva de aprendizado é baixíssima.
  • ✅ Sem Herança Obrigatória: Você não precisa herdar de classes como Profile para tudo, embora possa organizar seus mapeamentos de forma similar.

Mão na Massa: Implementação

1. Instalação dos Pacotes

dotnet add package Mapster
dotnet add package Mapster.DependencyInjection
Enter fullscreen mode Exit fullscreen mode

2. Configurando o Mapeamento (O novo "Profile")

No Mapster, utilizamos a interface IRegister. Veja como fica um mapeamento genérico de um DTO de usuário:

public class UsuarioMapping : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Usuario, UsuarioDto>()
            .Map(dest => dest.NomeCompleto, src => $"{src.FirstName} {src.LastName}")
            .Map(dest => dest.DataCadastro, src => src.CreatedAt)
            .Ignore(dest => dest.SenhaHash) // Segurança em primeiro lugar!
            .AfterMapping((src, dest) => {
                // Lógica customizada pós-mapeamento
                dest.UltimoAcesso = DateTime.Now;
            });
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Registro na Injeção de Dependência

No seu Program.cs, a configuração é muito limpa. Ele faz o scan automático de todos os seus mapeamentos:

// Registra o Mapster
var config = TypeAdapterConfig.GlobalSettings;
config.Scan(Assembly.GetExecutingAssembly());

builder.Services.AddSingleton(config);
builder.Services.AddScoped<IMapper, ServiceMapper>();
Enter fullscreen mode Exit fullscreen mode

Diferenças Práticas: De AutoMapper para Mapster

Para facilitar a sua vida na hora de converter os mapeamentos, aqui está um "de-para" rápido das operações que mais usamos no dia a dia:

1. Configuração Inicial

No AutoMapper, herdamos de Profile. No Mapster, implementamos IRegister.

  • AutoMapper: public class MyProfile : Profile
  • Mapster: public class MyMapping : IRegister

2. Mapeamento de Membros

A sintaxe muda de .ForMember para um simples .Map.

  • AutoMapper:

    .ForMember(dest => dest.Nome, opt => opt.MapFrom(src => src.FullName))
    
  • Mapster:

    .Map(dest => dest.Nome, src => src.FullName)
    

3. Ignorar Campos

Mais direto e sem a necessidade de abrir uma expressão de opção.

  • AutoMapper:

    .ForMember(dest => dest.Senha, opt => opt.Ignore())
    
  • Mapster:

    .Ignore(dest => dest.Senha)
    

4. Lógica Pós-Mapeamento

O AfterMap vira AfterMapping.

  • AutoMapper:

    .AfterMap((src, dest) => dest.Data = DateTime.Now)
    
  • Mapster:

    .AfterMapping((src, dest) => {
        dest.Data = DateTime.Now;
    })
    

5. Mapeamento de Mão Dupla

Se você precisa que o mapeamento funcione nos dois sentidos (Src -> Dest e Dest -> Src).

  • AutoMapper: .ReverseMap()
  • Mapster: .TwoWays()

Uso no Dia a Dia (Services/Controllers)

O uso continua sendo via injeção de dependência, o que significa que você quase não altera seu código de negócio:

public class PedidoService
{
    private readonly IMapper _mapper;

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

    public async Task<PedidoDto> ProcessarPedido(Pedido pedido)
    {
        // A chamada é idêntica!
        var dto = _mapper.Map<PedidoDto>(pedido);
        return dto;
    }
}
Enter fullscreen mode Exit fullscreen mode

Resultados Obtidos

Após a migração, notamos benefícios imediatos:

  1. Segurança: Vulnerabilidades da versão gratuita do AutoMapper eliminadas.
  2. Compliance: Sem preocupações com custos inesperados de licenciamento.
  3. Velocidade: Redução perceptível no tempo de processamento de mapeamentos complexos em listas grandes.

Conclusão

Mudar de biblioteca nem sempre é uma escolha fácil, mas quando envolve segurança e sustentabilidade financeira do projeto, é uma decisão necessária. O Mapster provou ser uma ferramenta superior em performance e extremamente amigável para quem está vindo do ecossistema AutoMapper.

Se você está rodando versões antigas do AutoMapper, recomendo fortemente avaliar essa migração. É o tipo de melhoria técnica que "se paga" no primeiro deploy.

Espero que esse guia ajude vocês nessa jornada! Dúvidas? Deixa nos comentários! 👇


#backend #mapping #mapster #dotnet #braziliandevs #performance #security #opensource

Top comments (0)