При разработке приложений частенько приходится сталкиваться с задачей преобразования одного объекта в другой. Этот процесс можно немного облегчить используя уже готовые библиотеки. Здесь я приведу пример на основе уже достаточно известной библиотеки Automapper.
Прежде чем приступить к рассмотрению маппига, хочу привести несколько ситуаций когда это может потребоваться:
- преобразование иерархической модели объектов в плоскую;
- получение проекций объектов (из доменного объекта генерируем ViewModel);
- получение доменного объекта из DTO;
- преобразование доменных объектов в сериализуемые объекты для передачи через какую-либо коммуникационную среду.
Иными словами маппинг нужен там, где объект переходит за границы приложения/уровня/слоя/компонента/...
Для того, чтобы начать использовать automapper, установим библиотеку из Nuget:
Install-Package AutoMapper
Для эксперимента создадим два объекта - UserDto
и User
.
public class UserDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
public class User
{
public string FullName { get; set; }
public string Email { get; set; }
}
При маппинге из UserDto
в User
, нам нужно заполнить поле FullName
путем объединения свойств FirstName
и LastName
исходного объекта.
Используя объект Mapper
, создадим конфигурацию маппера:
Mapper.CreateMap<UserDto, User>()
.ForMember(x => x.FullName,
x => x.MapFrom(m => m.FirstName + " " + m.LastName))
.ForMember(x => x.Email,
x => x.MapFrom(m => m.Email));
Запись эта интуитивно понятна и задает правила каким образом нужно маппить один объект в другой.
Маппинг выполняется также в одну строчку:
User user = Mapper.Map<User>(new UserDto
{
FirstName = "Ivan",
LastName = "Ivanov",
Email = "ivan@ivanon.ru"
});
Что интересно, в данном примере правило маппинга для свойства Email
избыточно, поскольку Automapper сам сопоставляет поля по имени и типу. Соответственно это правила можно переписать следующим образом:
Mapper.CreateMap<UserDto, User>()
.ForMember(x => x.FullName,
x => x.MapFrom(m => m.FirstName + " " + m.LastName));
Результат при этом не изменится.
Это самый простой способ использования библиотеки Automapper, вот более полный список возможностей библиотеки:
- Flattening (преобразование сложной иерархической объектной структуры в простой объект с несколькими полями)
- Projection (получение из исходного объекта его проекции, пример выше)
- Работа со списками
- Маппинг вложенных объектов
- Маппинги с условиями
Следует отметить, что регистрация правил действует в рамках домена приложения (AppDomain
). Если ваше приложение использует несколько доменов, то в каждом из них следует зарегистрировать эти правила.