AutoMapper и сопоставления вложенных объектов для инкапсуляции

Я не очень хорошо знаком с automapper, но наш архитектор программного обеспечения предложил мне его для этого проекта.

Концепция представляет собой полную инкапсуляцию волатильности. Вот плохо сделанная схема

API/уровень представления | Объекты с суффиксами запроса и ответа. (т.е. ApplicationCreateRequest)


Бизнес-уровень | Дом объектов передачи домена, суффикс DTO. (т.е. ApplicationCreateDTO)


Уровень базы данных | Домашняя страница объектов доступа к ресурсам и сущностей с суффиксами RAO и Entity (т. е. ApplicationEntity, ApplicationCreateRAO)

Мне нужно преобразовать ApplicationCreateRequests в ApplicationCreateDTO, а также преобразовать вложенные объекты Requests в DTO.

Например:

public class ApplicationCreateRequest
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public ContactCreateRequest Contact { get; set; }
    public DemographicCreateRequest Demographic { get; set; }
    public EducationCreateRequest Education { get; set; }
    public WorkCreateRequest Work { get; set; }
}

становится

public class ApplicationCreateDTO
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public ContactCreateDTO Contact { get; set; }
    public DemographicCreateDTO Demographic { get; set; }
    public EducationCreateDTO Education { get; set; }
    public WorkCreateDTO Work { get; set; }
}

DTO и запросы имеют по большей части одни и те же свойства.

Мне приходилось работать только с очень простыми сопоставлениями, такими как:

CreateMap<ObjectOne, ObjectTwo>(); 

person T. Deeter    schedule 09.11.2018    source источник


Ответы (1)


Простой способ сопоставить сложную модель - объявить и сопоставить их от самых простых (с собственными типами, например: strings, int,...) к сложным.

Таким образом, вы должны создать простые сопоставления для ContactCreateRequest и ContactCreateDTO с помощью CreateMap (и других простейших). Затем вам нужно будет создать что-то вроде:

MapFrom позволяет вам указать свойство (причина в том, что оно называется по-другому) для сопоставления. Это также позволяет вам указать результат из предварительно определенного сопоставления, вы просто указываете ему члена, из которого хотите сопоставить...

Mapper.CreateMap<ApplicationCreateRequest, ApplicationCreateDTO>()
    .ForMember(g => g.FirstName, opt => opt.MapFrom(src => src.FirstName));
    .ForMember(g => g.LastName, opt => opt.MapFrom(src => src.LastName));
    .ForMember(g => g.Contact, opt => opt.MapFrom(src => Mapper.Map<ContactCreateRequest,ContactCreateDTO>(g.Contact)));
    .ForMember(g => g.Demographic, opt => opt.MapFrom(src => Mapper.Map<DemographicCreateRequest,DemographicCreateDTO>(g.Demographic)));
    .ForMember(g => g.Education, opt => opt.MapFrom(src => Mapper.Map<EducationCreateRequest,EducationCreateDTO>(g.Education)));
    .ForMember(g => g.Work, opt => opt.MapFrom(src => Mapper.Map<WorkCreateRequest,WorkCreateDTO>(g.Work)));

Вы можете создать с помощью

.ForMember(g => g.Property, opt => opt.Ignore()); // чтобы игнорировать сопоставление свойства

Полезное замечание, определите базовое отображение перед сложными, иначе у вас будут проблемы!

Надеюсь это поможет.

person Minus    schedule 09.11.2018