Índice |
---|
Ao trabalhar com um modelo multicamada precisamos em muitos cenários realizar o mapeamento de objetos entre camadas de aplicação, domínio e infraestrutura.
O TNF traz facilitadores para mapear objetos e entidades para estruturas de DTO utilizando o AutoMapper.
Para uso dessa funcionalidade instale o pacote via nuget Tnf.App.AutoMapper disponível em: https://www.myget.org/F/tnf/api/v3/index.json
Para utilizar os mapeamentos via atributos lembre-se de colocar o módulo TnfAutoMapperModule como dependência em sua aplicação.
Para fazer isso use o atributo "DependsOn" para informar a dependência em seu módulo:
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn(
typeof(TnfAutoMapperModule))]
public class SampleModule : TnfModule
{
public override void PreInitialize()
{
base.PreInitialize();
}
} |
O exemplo abaixo exibe uma forma da utilização do AutoMapper de forma manual:
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public SearchPeopleOutput SearchPeople(SearchPeopleInput input)
{
var peopleEntityList = _personRepository.GetAllList(person => person.Name.Contains(input.SearchedName));
return new SearchPeopleOutput()
{
People = Mapper.Map<List<PersonDto>>(peopleEntityList)
};
} |
Como o AutoMapper precisa ser configurado (definidos os mapeamentos), sugerimos que isso seja feito através do seu módulo (TnfModule).
No método PostInitialize de seus módulo realize seus mapeamentos.
Estão disponíveis atributos e métodos de extensão para definir mapeamentos: o atributo AutoMapAttribute para mapeamento bidirecional, AutoMapFromAttribute e AutoMapToAttribute para mapeamento de um sentido apenas.
O exemplo abaixo contém um mapeamento bidirecional com utilização via métodos de extensão:
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
using Tnf.App.AutoMapper;
// two-way mapping
[AutoMap(typeof(MyClass2))]
public class MyClass1
{
public string TestProp { get; set; }
}
public class MyClass2
{
public string TestProp { get; set; }
}
// extensions methods mapping
var obj1 = new MyClass1 { TestProp = "Test value" };
var obj2 = obj1.MapTo<MyClass2>();
// extensions methods mapping
var obj1 = new MyClass1 { TestProp = "Test value" };
var obj2 = new MyClass2();
obj1.MapTo(obj2); |
Em muitos cenários realizamos algum mapeamento que contém alguma regra onde a propriedade de origem nem sempre é a mesma propriedade de destino. Um exemplo deste cenário seria uma entidade persistida em banco de dados onde tenha dois campos: Nome e Sobrenome. Essa entidade ao ser mapeada para um DTO por exemplo pode ser representada por uma propriedade chamada NomeCompleto onde terá a junção de Nome e Sobrenome.
Para esses casos criamos profiles no AutoMapper onde configuramos todo e qualquer comportamento adicional a ser realizado no mapeamento de valores:
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class DtoToPocoProfile : Profile
{
public DtoToPocoProfile()
{
CreateMap<CountryDto, CountryPoco>()
.ForMember(d => d.Id, s => s.MapFrom(p => p.Id));
CreateMap<ProfessionalDto, ProfessionalPoco>()
.ForMember(d => d.Address, s => s.Ignore())
.ForMember(d => d.AddressComplement, s => s.Ignore())
.ForMember(d => d.AddressNumber, s => s.Ignore())
.ForMember(d => d.ZipCode, s => s.Ignore())
.ForMember(d => d.ProfessionalSpecialties, s => s.Ignore())
.AfterMap((s, d) =>
{
d.Address = s.Address.Street;
d.AddressComplement = s.Address.Complement;
d.AddressNumber = s.Address.Number;
d.ZipCode = s.Address.ZipCode.Number;
});
CreateMap<SpecialtyDto, SpecialtyPoco>();
CreateMap<PresidentDto, PresidentPoco>();
}
} |
A classe de exemplo acima representa a criação de um profile com mapeamentos customizados.
Para podermos utilizar esse profile devemos configura-lo em nosso modulo:
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn(
typeof(TnfAutoMapperModule))]
public class SampleModule : TnfModule
{
public override void PreInitialize()
{
base.PreInitialize();
Configuration.Modules
.TnfAutoMapper()
.Configurators
.Add(config =>
{
config.AddProfile(new DtoToPocoProfile());
});
}
} |