Nesta série de dois artigos, falarei sobre a biblioteca AutoMapper.
Neste primeiro, vão ser apresentados seus benefícios, e como adicioná-la em seu projeto. Finalmente, um exemplo será mostrado.
Já na segunda parte, serão mostrados exemplos de mapeamento mais complexos.
Código-fonte pode ser encontrado aqui.
Quer ser notificado sobre os próximos artigos, lives semanais, eventos e treinamentos? Entre no canal LuisDev no Telegram!
Mapeamento entre objetos
Antes de apresentar o AutoMapper, é essencial entender o problema a ser resolvido por ele.
Imagine a seguinte situação: você tem uma classe Pessoa, que tem diversas propriedades. Informações como documentos, data de nascimento, estado civil, entre outros, são armazenado nelas.
Como você é um bom programador, preocupado em manter a separação entre modelos de representação, você cria um modelo de entrada (ou Input Model), e uma entidade do domínio. A imagem abaixo representa ambas.
Com isso, toda vez que a classe Pessoa for alterada, você não arriscará afetar o cadastro dela, por exemplo. O modelo de entrada está centrado em PersonInputModel, enquanto o de domínio está em Person.
Considere que é necessário instanciar Person com os dados informados no modelo de entrada. Isso poderia ser feito utilizando um construtor vazio, e propriedades com setters públicos, ou com um construtor com os parâmetros necessários.
De uma maneira ou de outra, vai ficar abarrotado de parâmetros sendo passados. A classe Person tem muitas propriedades, e dentre elas várias estão também em PersonInputModel. Além disso, existe a chance de em outros lugares do seu código requerer instanciar esse objeto. O caminho inverso também é feito, no caso, de uma entidade do domínio para um modelo de saída (ou View Model).
Construtores com muitos parâmetros, setters públicos, e mais
Vou ser bem sincero. Já vi diversos desenvolvedores preferirem utilizar setters públicos e construtores sem parâmetros, devido à quantidade absurda de parâmetros. É algo que parece deixar tudo mais prático, porém o risco de se esquecer de aplicar uma alteração em diversas partes do sistema, ao usar esses construtores, é altíssimo (já vi inúmeras vezes isso). Construtores ajudariam a detectar essas alterações que quebram, mas um construtor com muitos parâmetros tampouco é muito prático.
Olha o exemplo abaixo de um mapeamento manual, explicado nas frases passadas.
E é para resolver este tipo de problema que o AutoMapper se propõe.
Introdução ao AutoMapper
O AutoMapper é uma biblioteca que ajuda a remover esse trabalho tedioso de mapear um objeto a outro. Ao invés de dependermos de construtores com muitos parâmetros, ou perder o feedback de regressão ao usar construtores sem parâmetro, utilizamos ela para fazer o trabalho de uma maneira bem mais confiável.
Instalando
Primeiramente, instalamos a biblioteca AutoMapper.Extensions.Microsoft.DependencyInjection, que vai nos fornecer o método de extensão para obter as classes que vão definir os mapeamentos. Como ela tem dependência no pacote “raiz” AutoMapper, ambos serão instalados juntos.
Utilizando o AutoMapper
Para começar a mapear entre objetos em sua aplicação, é necessário criar classes que descrevam como vai ser feito isso. Por mais que as classes entre si contenham a mesma nomenclatura de propriedades, isso é necessário.
Essas classes devem herdar da classe Profile, do namespace AutoMapper. Em seu construtor, os mapeamentos possíveis serão definidos.
Para este artigo, consideremos duas classes com propriedades de mesmo nome. Elas foram mostradas anteriormente: PersonInputModel, e Person.
Vamos criar uma classe Profile que vai mapear de PersonInputModel para Person, e vice-versa. Essa classe será chamada PersonProfile.
O que ela diz, basicamente, é: permita o mapeamento da primeira classe definida como parâmetro de tipo, para a segunda. Note que nenhum comportamento além do padrão é especificado.
Em seguida, configuraremos para que nossa aplicação a utilize. Adicionamos, na classe Startup, a chamada ao método IServiceCollection.AddAutoMapper, passando Assembly (ou tipo contido do Assembly) utilizado para obter os perfis de mapeamento.
Após isso, vamos criar um Controller, com um endpoint “api/person“. Ele permitirá uma requisição HTTP POST, contendo o PersonInputModel no corpo. Nele, é feita a conversão, e o objeto da entidade é retornado para o cliente.
Note que também foi criado um endpoint que com método HTTP GET, que retornará uma lista de PersonViewModel. Logo abaixo, é mostrada a implementação dessa classe (com as mesmas propriedades que PersonInputModel e Person).
Simples, não?
Testando
Para testar a implementação mostrada, utilizei o Postman. Na imagem abaixo, é realizada uma chamada HTTP POST ao endpoint api/people, com um objeto JSON. Note que as propriedades no objeto de retorno foram mapeadas corretamente.
Após isso, testamos o endpoint api/people/1, com uma requisição HTTP GET. O resultado é mostrado logo abaixo.
Que tal? É o máximo, certo?
Quer alavancar sua carreira como Desenvolvedor(a) .NET?
Opa, aqui é o Luis Felipe (LuisDev), criador do blog LuisDev.
Além de Desenvolvedor .NET Sênior, eu sou instrutor de mais de 700 alunos e também tenho dezenas de mentorados.
Conheça o com mais de 800 video-aulas sobre C# e desenvolvimento de APIs com ASP NET Core, Microsserviços com ASP NET Core, Arquitetura de Software, Computação em Nuvem, SQL, HTML, CSS e JavaScript, JavaScript Intermediário, TypeScript, Desenvolvimento Front-End com Angular, e Desenvolvimento Front-end com React. Diversos mini-cursos disponíveis aos alunos e atualizações gratuitas.
Suporte dedicado, e comunidade de centenas de alunos.
Completo e online, destinado a profissionais que querem dar seu próximo passo em sua carreira como desenvolvedores .NET.
Clique aqui para ter mais informações e garantir sua vaga
Realizar o mapeamento entre os objetos pode ser uma tarefa bem propensa a erros. Com a biblioteca AutoMapper, essa tarefa fica mamão com açúcar!
Na parte #2, irei mostrar alguns mapeamentos mais complexos, como o uso de descrição de Enums, mapeando de uma lista para um objeto, entre outros.
Nos vemos no próximo artigo!
Dev .NET Sênior com experiências para Irlanda e Estados Unidos, 2x Microsoft MVP, 9x Microsoft Certified, MBA em Arquitetura de Soluções, Fundador e Instrutor LuisDev Treinamentos,
Parabéns pelos artigos, são sensacionais!!
Muito obrigado pelo feedback, Paulo!