Índice |
---|
Quando trabalhamos em Ao trabalhar com um modelo multicamada precisamos em muitos cenários realizar o mapeamento de nossa entidade de infraestrutura (utilizada para representar a tabela do Entity Framework, o documento em um banco NoSQL, etc).objetos entre camadas de aplicação, domínio e infraestrutura.
O TNF traz facilitadores para Para isso o TNF tráz facilitadores na hora de mapear objetos e entidades para estruturas de DTO utilizando o AutoMapper.
Para obter suporte ao AutoMapper uso dessa funcionalidade instale o pacote via nuget Tnf.App.AutoMapper disponível em nosso package source: 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 da estrutura 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 pode ser seja feito através da estrutura de módulos do TNFdo seu módulo (TnfModule).
No método PostInitialize de um modulo criado para um assembly que realize o uso do AutoMapper, você pode configurar as entidades que serão mapeadasPostInitialize de seus módulo realize seus mapeamentos.
No TNF estão 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());
});
}
} |