8
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:

Tutorial Auto Mapper

Embed Size (px)

DESCRIPTION

Tutorial de como instalar e usar o automapper.

Citation preview

Page 1: Tutorial Auto Mapper

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:

Page 2: Tutorial Auto Mapper

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;

Page 3: Tutorial Auto Mapper

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)

Page 4: Tutorial Auto Mapper

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

Page 5: Tutorial Auto Mapper

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:

Page 6: Tutorial Auto Mapper

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; }

}

Page 7: Tutorial Auto Mapper

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.