Como especificar a regra de mapeamento quando os nomes das propriedades diferem

144

Eu sou um novato na estrutura Automapper. Eu tenho uma classe de domínio e uma classe DTO da seguinte maneira:

public class Employee
{
   public long Id {get;set;}
   public string Name {get;set;}
   public string Phone {get;set;}
   public string Fax {get;set;}
   public DateTime DateOfBirth {get;set;}
}

public class EmployeeDto
{
   public long Id {get;set;}
   public string FullName {get;set;}
   public DateTime DateOfBirth {get;set;}
}

Nota: O nome da propriedade " Name " da Employeeclasse não é igual ao da propriedade " FullName " da EmployeeDtoclasse.

E aqui está o código para mapear o Employeeobjeto EmployeeDto:

Mapper.CreateMap<Employee, EmployeeDto>(); // code line (***)
EmployeeDto dto = Mapper.Map<Employee, EmployeeDto>(employee); 

Minha pergunta é: Se eu quiser mapear Employee(classe de origem) para EmployeeDto(classe de destino), como posso especificar a regra de mapeamento? Em outras palavras, como devo fazer mais com a linha de código (***) acima?

Thomas.Benz
fonte

Respostas:

292

Não importa, eu mesmo encontrei uma solução:

Mapper.CreateMap<Employee, EmployeeDto>()
    .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name));
Thomas.Benz
fonte
1
Existe uma maneira de especificá-lo globalmente para qualquer classe, algo como prefixo / sufixo? Por exemplo, eu tenho várias classes de uma biblioteca que possuem a propriedade "Localizações" cada. E eu quero mapeá-los para classes onde a propriedade correspondente é chamada "LocalizedName". Minha única opção é adicionar ForMember a cada configuração de mapeamento?
NickAb #
2
não há método CreateMap na classe Mapper :(
Navid_pdp11 20/07
3
@ Navid_pdp11 sim, existe. Você precisa ter a classe Mapper estático não uma instância
Jordy van Eijk
@JordyvanEijk Qual versão você está usando que tem um método estático "CreateMap"? Em 5.1.1.0 não há tal coisa
Matt Thomas
6
@MattThomas Depois de dar uma olhada no github do automapper, vejo que, na versão 5.0, o CreateMap é obsoleto e eles dizem que você precisa usar o MapperConfiguration ou Mapper.Initialize.
Jordy van Eijk 10/10
7

Apenas para rolar os comentários acima em uma abordagem atualizada usando o Automapper 8.1 + ...

var mapConfig = new MapperConfiguration(
   cfg => cfg.CreateMap<Employee, EmployeeDto>()
      .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.Name))
);

Em seguida, você criaria o mapeador usando o mapConfig:

var mapper = mapConfig.CreateMapper();
ebol2000
fonte
2

Também podemos especificar atributos de classe para mapeamento

De https://docs.automapper.org/en/stable/Conventions.html#attribute-support

Suporte a Atributos

AddMemberConfiguration().AddName<SourceToDestinationNameMapperAttributesMember>(); * Atualmente, está sempre ativado

Procura instâncias de SourceToDestinationMapperAttribute for Properties / Fields e chama a função isMatch definida pelo usuário para encontrar correspondências de membros.

MapToAttribute é um deles que corresponderá à propriedade com base no nome fornecido.

public class Foo
{
    [MapTo("SourceOfBar")]
    public int Bar { get; set; }
}
Pranay DevOps
fonte
Ao citar conteúdo de outro lugar literalmente, use a formatação de cotações em bloco para deixar claro aos leitores que o conteúdo foi copiado.
TylerH 13/03
Confira o novo estilo :) docs.automapper.org/en/latest/Attribute-mapping.html
Lucian Bargaoanu 14/03
Muito novo no stackoverflow. Claro que seguirá as regras @TylerH
Pranay DevOps