Я несколько новичок в AutoMapper и хотел сопоставить объект POCO-ish с возможно более сложным DTO, последний пытается быть представлением Ресурс API Google Книги:
Book.cs
public class Book
{
public string Isbn10 { get; set; }
public string Isbn13 { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Publisher { get; set; }
public DateTime Publication { get; set; }
public int Pages { get; set; }
public string Description { get; set; }
public bool InStock { get; set; }
}
BookDto.cs
public class BookDto
{
public string Kind { get; set; }
public string Id { get; set; }
public VolumeInfo VolumeInfo { get; set; }
}
public class VolumeInfo
{
public string Title { get; set; }
public List<string> Authors { get; set; }
public string Publisher { get; set; }
public string PublishedDate { get; set; }
public string Description { get; set; }
public int PageCount { get; set; }
public List<IndustryIdentifier> IndustryIdentifiers { get; set; }
}
public class IndustryIdentifier
{
public string Type { get; set; }
public string Identifier { get; set; }
}
Итак, согласно документации мы могли бы просто сгладить вложенный тип:
AutoMapperConfigurator.cs
public static class AutoMapperConfigurator
{
public static void Configure()
{
Mapper.CreateMap<Book, BookDto>()
.ForMember(dto => dto.Id, options => options.Ignore())
.ForMember(dto => dto.Kind, options => options.Ignore())
.ForMember(dto => dto.VolumeInfo.Title, options => options.MapFrom(book => book.Title))
.ForMember(dto => dto.VolumeInfo.Authors, options => options.MapFrom(book => book.Author.ToArray()))
.ForMember(dto => dto.VolumeInfo.Publisher, options => options.MapFrom(book => book.Publisher))
.ForMember(dto => dto.VolumeInfo.PublishedDate, options => options.MapFrom(book => book.Publication))
.ForMember(dto => dto.VolumeInfo.Description, options => options.MapFrom(book => book.Description))
.ForMember(dto => dto.VolumeInfo.PageCount, options => options.MapFrom(book => book.Pages))
;
}
}
Но, к сожалению, при запуске теста Mapper.AssertConfigurationIsValid()
я получаю следующую ошибку:
System.ArgumentException: выражение 'dto = > dto.VolumeInfo.Title' должен разрешаться для члена верхнего уровня, а не для любого дочернего объекта свойства. Используйте настраиваемый распознаватель для дочернего типа или AfterMap вместо этого. Имя параметра: lambdaExpression
Итак, теперь после этого совета, пытающегося использовать AfterMap:
public static class AutoMapperConfigurator
{
public static void Configure()
{
Mapper.CreateMap<Book, BookDto>()
.ForMember(dto => dto.Id, options => options.Ignore())
.ForMember(dto => dto.Kind, options => options.Ignore())
.AfterMap((book, bookDto) => bookDto.VolumeInfo = new VolumeInfo
{
Title = book.Title,
Authors = new List<string>(){ book.Author },
Publisher = book.Publisher,
PublishedDate = book.Publication.ToShortDateString(),
Description = book.Description,
PageCount = book.Pages
});
}
}
При повторном тестировании я получаю следующее сообщение:
Найдены неподключенные элементы. Просмотрите типы и элементы ниже. Добавить пользовательское отображение, игнорирование, добавление настраиваемого распознавателя или изменение тип источника/назначения → BookDto (список участников) Dotnet.Samples.AutoMapper.Book → Dotnet.Samples.AutoMapper.BookDto(Список членов назначения) VolumeInfo
Должен ли я создавать дополнительные сопоставления между вложенными классами? Любые указания будут искренне оценены, спасибо заблаговременно.