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:
Vulnerabilidade CrÃtica: A versão 13 (gratuita) do AutoMapper apresenta vulnerabilidades conhecidas que podem comprometer a segurança da aplicação.
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
Profilepara 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
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;
});
}
}
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>();
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;
}
}
Resultados Obtidos
Após a migração, notamos benefÃcios imediatos:
- Segurança: Vulnerabilidades da versão gratuita do AutoMapper eliminadas.
- Compliance: Sem preocupações com custos inesperados de licenciamento.
- 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)