Upload
alisson-pereira-anjos
View
238
Download
1
Embed Size (px)
DESCRIPTION
Tutorial de como instalar e usar o automapper.
Citation preview
Automapper – Tutorial Criado por Alisson Pereira
O AutoMapper é uma biblioteca pequena e simples construída
para resolver um problema aparentemente complexo, que é
livrar-se de um código que mapeou um objeto para outro. Este
tipo de problema é muito comum e relativamente trabalhoso de
resolver, a ferramenta AutoMapper atua nesse cenário de forma
simples e elegante.
Mapeamento de um Model para uma Entidade:
Entidade Cliente:
ViewModel Cliente:
Na classe ClienteViewModel possuímos a mesma estrutura de clientes, mais o dado adicional de número da sorte e os DataAnnotations para validação de formulário.
Após a separação das responsabilidades temos uma Model e uma View Model, ambas representando a entidade cliente, agora é necessário mapear um objeto ao outro para que a ClienteController receba a Model cliente e responda para View uma ClienteViewModel (e vice-versa), esse trabalho é executado pelo AutoMapper.
Configurando o AutoMapper no projeto ASP.Net MVC
Primeiramente é necessário configurar as referências das bibliotecas do AutoMapper e isto pode ser feito facilmente com o NuGet
(install-package AutoMapper)
No projeto MVC crie uma pasta vazia chamada Mappers, dentro desta pasta será necessário criar uma classe que servirá de configuração dos profiles de mapeamento (Model > View Model) e (View Model > Model), esses profiles de mapeamento foram separados em dois arquivos, confira como abaixo como criar cada um deles.
Classe AutoMapperConfig
using AutoMapper;
namespace MvcMapping.Mappers{ public class AutoMapperConfig { public static void RegisterMappings() { Mapper.Initialize(x => { x.AddProfile<DomainToViewModelMappingProfile>(); x.AddProfile<ViewModelToDomainMappingProfile>(); }); } }}
Classe DomainToViewModelMappingProfile
using AutoMapper;using MvcMapping.Models;
using MvcMapping.ViewModels;
namespace MvcMapping.Mappers{ public class DomainToViewModelMappingProfile : Profile { public override string ProfileName { get { return "DomainToViewModelMappings"; } }
protected override void Configure() { Mapper.CreateMap<Cliente, ClienteViewModel>(); } }}
Classe ViewModelToDomainMappingProfile
using AutoMapper;using MvcMapping.Models;using MvcMapping.ViewModels;
namespace MvcMapping.Mappers{ public class ViewModelToDomainMappingProfile : Profile { public override string ProfileName { get { return "ViewModelToDomainMappings"; } }
protected override void Configure() { Mapper.CreateMap<ClienteViewModel, Cliente>(); } }}
Esta é a estrutura necessária para configurar o AutoMapper de forma a utilizar o mínimo possível de código de mapeamento em outras classes da aplicação.
AutoMapperConfig > Inicializa os profiles de mapeamento
(Model > View Model) e (ViewModel > Model).
DomainToViewModelMappingProfile > Profile de
mapeamento (Model > View Model)
ViewModelToDomainMappingProfile > Profile de
mapeamento (View Model > Model)
Confira como o projeto ficou estruturado
Neste momento resta apenas configurar que a classe AutoMapperConfig seja inicializada junto com a aplicação para registrar os profiles de mapeamento, essa configuração é feita no arquivo Global.asax
Application_Start
AutoMapperConfig.RegisterMappings();
Agora será feito a conversão do model Cliente para o ClienteViewModel
AutoMapper.Mapper.CreateMap<Origem, Destino>();
// Transformando a Model Cliente em ClienteViewModelvar clienteView = Mapper.Map<Cliente, ClienteViewModel>(cliente);
// Atribuindo valor aos dados adicionais da entidade ClienteclienteView.NumeroDaSorte = rdnGen.Next(1, 100);
Note que foi necessário apenas uma linha para transformar a Model Cliente em ClienteViewModel. De forma muito elegante foi criado um objeto do tipo ClienteViewModel já populado com os dados existentes no objeto Cliente.
Para mapear mais Models / View Models basta editar os arquivos DomainToViewModelMappingProfile e ViewModelToDomainMappingProfile com os mapeamentos necessários.
Existe uma forma que dispensa toda essa configuração (inclusive inicialização no Global.asax), basta adicionar uma linha a mais em cada momento que houver o mapeamento, conhecido como mapeamento por demanda.
// Criando o Mapeamento por demanda.Mapper.CreateMap<Cliente, ClienteViewModel>();
// Transformando a Model Cliente em ClienteViewModelvar clienteView = Mapper.Map<Cliente, ClienteViewModel>(cliente);
// Atribuindo valor aos dados adicionais da entidade ClienteclienteView.NumeroDaSorte = rdnGen.Next(1, 100);
Apesar de ser mais simples eu pessoalmente não recomendo utilizar o mapeamento desta forma, pois além de somar uma linha a mais em todo momento de executar o mapeamento, o comando de criação de mapeamento não fica centralizado, é difícil ter visão dos mapeamentos já existentes e dificulta também a manutenção.
Para situações onde é necessário que aconteça o mapeamento de um atributo x para um atributo y é necessário especificar no mapeamento do AutoMapper (de quem para quem será mapeado).
Exemplo 1:
public class Book
{
public string Title { get; set; }
}
public class BadBookViewModel
{
public string BookTitle { get; set; }
}
No exemplo acima será mapeado o atributo Title da classe Book para o atributo BookTitle da classe BadBookViewModel, para realizar esse tipo de mapeamento é necessário seguir o exemplo abaixo.
AutoMapper.Mapper.CreateMap<Book, BadBookViewModel>()
.ForMember(dest => dest.BookTitle,
opts => opts.MapFrom(src => src.Title));
Onde é especificado que no mapeamento de book para badBookViewModel irá mapear o atributo title para bookTitle.
Exemplo 2:
public class Author
{
public string Name { get; set; }
}
public class Book
{
public string Title { get; set; }
public Author Author { get; set; }
}
public class BookViewModel
{
public string Title { get; set; }
public string Author { get; set; }
}
Mapeando Book.Author.Name para BookViewModel.Author ou seja mapeando um atributo (Name) da entidade chamada Author que por si é um atributo da class Book para o atributo string da class BookViewModel.
AutoMapper.Mapper.CreateMap<Book, BookViewModel>()
.ForMember(dest => dest.Author,
opts => opts.MapFrom(src => src.Author.Name));
Extras
1) Mapeando uma lista:
var destinationList = AutoMapper.Mapper.Map<List<Destino>>(origem);
2) Ignorar o mapeamento de uma propriedade:
AutoMapper.Mapper.CreateMap<PersonDTO, Person>()
.ForMember(dest => dest.Pets,
opts => opts.Ignore());
Utilizar Ignore para impedir o mapeamento do atributo x, no exemplo acima o atributo é o Pets.