O AutoMapper é uma biblioteca popular em C# para mapeamento de objetos, facilitando a transformação de dados entre camadas. No entanto, recentemente foi anunciado que o AutoMapper passará a ser pago. Neste artigo, vamos explorar alternativas gratuitas e de código aberto, como TinyMapper, ExpressMapper e Mapster, destacando suas funcionalidades.

A necessidade de ferramentas para mapeamento de objetos

No desenvolvimento de software, é comum precisar realizar a transformação de dados entre diferentes tipos de objetos. Por exemplo, ao trabalhar com camadas distintas em uma aplicação, como a camada de persistência de dados (entidades) e a camada de apresentação (DTOs), a conversão entre esses tipos de objetos é fundamental. Realizar esse mapeamento manualmente pode ser demorado e propenso a erros, além de tornar o código mais difícil de manter.

Por isso, ferramentas que automatizam esse processo de mapeamento tornam-se essenciais. Elas permitem que os desenvolvedores se concentrem nas regras de negócios e na lógica da aplicação, enquanto a ferramenta cuida da transformação dos dados.

TinyMapper

O TinyMapper é uma das alternativas mais simples e focadas em desempenho. Sua proposta é ser leve e extremamente rápida, fornecendo uma solução sem dependências adicionais e uma API de configuração simples.

 

Para instalar o TinyMapper, adicione o pacote pelo .NET CLI ou NuGet no seu projeto:

				
					.NET CLI:
dotnet add package TinyMapper

NuGet:
Install-Package TinyMapper

				
			

O TinyMapper não exige configurações complexas. Basta informar quais objetos serão mapeados. Isso pode ser feito no “Program.cs” ou em outro local adequado:

				
					TinyMapper.Bind<Endereco, EnderecoDTO>();
				
			

O mapeamento é feito automaticamente com base nas propriedades que possuem o mesmo nome entre as classes de origem e destino.

				
					var enderecoInicial = new Endereco { 
    Id = 1, 
    Rua = "Av. Paulista", 
    Cidade = "São Paulo", 
    Estado = "São Paulo", 
    CEP="64000000" };

var enderecoFinal = TinyMapper.Map<EnderecoDTO>(enderecoInicial);

				
			

Mapeamento personalizado

Para casos mais específicos, é possível usar mapeamentos personalizados.

				
					TinyMapper.Bind<Endereco, EnderecoDTO>(c =>
{
    c.Ignore(s => s.Id);
    c.Bind(s => s.Avenida, d => d.Rua);
    c.Bind(s => s.NumeroCEP, d => d.CEP);
    c.Bind(s => s.NomeCidade, d => d.Cidade);
    c.Bind(s => s.NomeEstado, d => d.Estado);
});

				
			

No exemplo acima, temos dois objetos cujas propriedades possuem nomes diferentes. É possível omitir o mapeamento de uma propriedade, como foi feito com o “Id”, e também especificar explicitamente qual propriedade de um objeto deve ser mapeada para outra.

Mapeamento objetos aninhados

O TinyMapper também oferece suporte para mapear objetos aninhados. Você pode fazer isso especificando manualmente como cada propriedade do objeto interno deve ser mapeada. Para esse exemplo e os demais vamos usar esse objeto:

				
					public class Endereco
{
    public string Rua { get; set; }
    public string Cidade { get; set; }
}

public class Pessoa
{
    public string Nome { get; set; }
    public Endereco Endereco { get; set; }
}

				
			

Podemos mapear “Pessoa” para “PessoaDTO”, incluindo o “Endereco”, dessa forma:

				
					TinyMapper.Bind<Pessoa, PessoaDTO>(config =>
{
    config.Bind(s => s.Nome, d => d.Nome);     
    config.Bind(s => s.Endereco.Rua, d => d.Endereco.Rua);     
    config.Bind(s => s.Endereco.Cidade, d => d.Endereco.Cidade); 
});

				
			

ou desta outra maneira:

				
					TinyMapper.Bind<Endereco, EnderecoDTO>(config =>
{
    config.Bind(s => s.Rua, d => d.Rua);
    config.Bind(s => s.Cidade, d => d.Cidade);
});

TinyMapper.Bind<Pessoa, PessoaDTO>(config =>
{
    config.Bind(s => s.Nome, d => d.Nome);
    config.Bind(s => s.Endereco, d => d.Endereco);
});

				
			

Na primeira forma,  mapeamos as propriedades dentro do objeto “Endereco” diretamente para as propriedades do “PessoaDTO”. Esse tipo de mapeamento é fácil de implementar quando você lida com objetos aninhados com um número reduzido de níveis.

Já na segunda forma, nós criamos um mapeamento para “Pessoa” e outro para “Endereco”. Quando “Pessoa” precisa realizar o mapeamento do objeto “Endereco”, ele já sabe como deve proceder.

ExpressMapper

O ExpressMapper é uma alternativa que se destaca pela configuração rápida e por oferecer suporte a expressões Lambda para personalizar mapeamentos. Ele foca na simplicidade e flexibilidade, permitindo um mapeamento rápido e eficiente.

Para instalar o ExpressMapper, adicione o pacote NuGet no seu projeto:

				
					.NET CLI:
dotnet add package Expressmapper

NuGet:
Install-Package ExpressMapper

				
			

A configuração básica do ExpressMapper é rápida e direta. Basta registrar o mapeamento entre as classes de origem e destino:

				
					ExpressMapper.Mapper.Register<Endereco, EnderecoDTO>();

var enderecoInicial = new Endereco { 
    Id = 1, 
    Rua = "Av. Paulista", 
    Cidade = "São Paulo", 
    Estado = "São Paulo", 
    CEP="64000000" }; 

				
			

O mapeamento é feito automaticamente, usando as convenções de nome de propriedades. Para realizar o mapeamento:

				
					var enderecoFinal = ExpressMapper.Mapper.Map<Endereco, EnderecoDTO>(enderecoInicial);
				
			

Mapeamento personalizado

Caso precise de mapeamentos mais específicos, como quando as propriedades de origem e destino possuem nomes diferentes, você pode usar expressões Lambda para personalizar a transformação de dados:

				
					ExpressMapper.Mapper.Register<Endereco, EnderecoDTO>()
     .Ignore(dest => dest.Id)
     .Member(dest => dest.Rua, orig => orig.Avenida)
     .Member(dest => dest.CEP, orig => orig.NumeroCEP)
     .Member(dest => dest.Cidade, orig => orig.NomeCidade)
     .Member(dest => dest.Estado, orig => orig.NomeEstado);

				
			

No exemplo acima, o ExpressMapper permite personalizar o mapeamento, especificando que a propriedade “Id” não deve ser mapeada usando “Ignore”. Após isso usamos o método “Member” para ligar o parâmetro de destino com o de origem.

Mapeamento objetos aninhados

Para realizarmos o mapeamento de objetos aninhados no ExpressMapper, podemos fazer da seguinte forma:

				
					ExpressMapper.Mapper.Register<Pessoa, PessoaDTO>()
 .Member(s => s.Nome, d => d.Nome)
 .Member(s => s.Endereco.Rua, d => d.Endereco.Rua)
 .Member(s => s.Endereco.Cidade, d => d.Endereco.Cidade);

				
			

ou

				
					ExpressMapper.Mapper.Register<Endereco, EnderecoDTO>();
ExpressMapper.Mapper.Register<Pessoa, PessoaDTO>()
.Member(s => s.Nome, d => d.Nome)
.Member(s => s.Endereco, d => d.Endereco);

				
			

Semelhante ao TinyMapper, podemos realizar o mapeamento do objeto “Endereco” dentro de “Pessoa” ou podemos realizar o seu mapeamento separadamente.

Mapster

O Mapster é uma das alternativas mais poderosas e flexíveis ao AutoMapper. Ele suporta mapeamento manual, via configuração ou atributos, tornando-se ideal para projetos mais complexos que exigem flexibilidade e personalização.

Para instalar o Mapster, adicione o pacote NuGet no seu projeto:

				
					.NET CLI:
dotnet add package Mapster

NuGet:
Install-Package Mapster

				
			

A configuração básica do Mapster pode ser feita diretamente, registrando a configuração do mapeamento:

				
					TypeAdapterConfig<Endereco, EnderecoDTO>.NewConfig();   
				
			

O mapeamento pode ser feita da seguinte forma:

				
					var enderecoInicial = new Endereco { 
    Id = 1, 
    Rua = "Av. Paulista", 
    Cidade = "São Paulo", 
    Estado = "São Paulo", 
    CEP="64000000" };

	 var enderecoFinal = enderecoInicial.Adapt<EnderecoDTO>();

				
			

O Mapster utiliza o método “Adapt<T>()”, que é um método de extensão da classe “Object”. Isso significa que todos os tipos de objetos em C# podem utilizar esse método para se adaptar a outro tipo. Portanto, ao utilizar “enderecoInicial.Adapt<EnderecoDTO>()”, o Mapster mapeia as propriedades do tipo “Endereco” para o tipo “EnderecoDTO”, com base nas convenções de nome, de forma eficiente e sem a necessidade de configuração manual.

Mapeamento personalizado

Ele também permite criar mapeamentos personalizados utilizando a API de configuração para adaptar o mapeamento entre as propriedades de objetos com nomes diferentes:

				
					TypeAdapterConfig<Endereco, EnderecoDTO>.NewConfig()
    .Ignore(dest => dest.Id)
    .Map(dest => dest.Rua, orig => orig.Avenida)           
    .Map(dest => dest.Cidade, orig => orig.NomeCidade)        
    .Map(dest => dest.Estado, orig => orig.NomeEstado)        
    .Map(dest => dest.CEP, orig => orig.NumeroCEP); 

				
			

Neste exemplo, o Mapster permite que você defina explicitamente como cada propriedade de um objeto deve ser mapeada para outra. Essa flexibilidade é particularmente útil quando as propriedades não seguem convenções de nomeamento.

Mapeamento objetos aninhados

O Mapster lida automaticamente com objetos aninhados e ainda permite configurações personalizadas e mapeamento por atributo, tornando-o uma excelente escolha para cenários mais complexos.

				
					TypeAdapterConfig<Pessoa, PessoaDTO>.NewConfig()
.Map(s => s.Nome, d => d.Nome)
.Map(s => s.Endereco, d => d.Endereco);

				
			

No exemplo acima, o Mapster realiza o mapeamento do “Endereco” automaticamente, sem a necessidade de configurar manualmente cada propriedade dentro do objeto “Endereco”.

Acelere a sua carreira conosco!

Se você é Desenvolvedor .NET Júnior e quer acelerar sua carreira até nível Pleno com salário de R$7k+, ou mesmo busca a primeira vaga, conheça a Mentoria .NET StartClique aqui

Se é Desenvolvedor .NET Pleno ou Sênior e quer virar referência técnica em sua equipe e mercado, com salário de R$10k+, conheça a Mentoria .NET ExpertClique aqui

Conclusão

Ferramentas para mapeamento como TinyMapper, ExpressMapper e Mapster oferecem soluções gratuitas e eficientes para o mapeamento de objetos em C#. Cada ferramenta tem suas vantagens, dependendo do tamanho e complexidade do projeto. A escolha vai depender das necessidades específicas do seu projeto, mas todas as alternativas apresentam boas opções para substituir o AutoMapper de maneira eficaz.