#c# #automapper-10
#c# #automapper-10
Вопрос:
В моем проекте я пытаюсь использовать automapper, чтобы максимально приблизить мои командные объекты к объектам моего домена по соглашению.
Это работает, когда я явно сопоставляю два элемента в профиле сопоставления, но, согласно документации automapper, я думаю, что это также должно работать по соглашению. Я создал dotnetfiddle, чтобы продемонстрировать минимальный случай.
Связанные вопросы заканчиваются тем, что люди явно добавляют сопоставление, но это противоречит тому, для чего создан Automapper, и противоречит документации, нет? Это также не работает с выравниванием, поэтому reversemap — это отвлекающий маневр, я думаю.
Отображение
public class Mapping: Profile
{
public Mapping()
{
this.CreateMap<CreateSelectionCommand, Selection>();
// .ForMember(selection => selection.Name, opt => opt.MapFrom(x => x.SelectionName))
.reverseMap()
}
}
Что я ожидаю от работы
[Fact]
public void ShouldMapName()
{
var cmd = new CreateSelectionCommand {SelectionName = "selectionName"};
var selection = _mapper.Map<Selection>(cmd);
Assert.Equal(cmd.SelectionName, selection.Name); <== selection.Name == ""
}
Классы для контекста
public class Selection
{
public string Name { get; set; }
}
public class CreateSelectionCommand
{
public string SelectionName { get; set; }
}
Я неправильно прочитал документы или я что-то упустил?
Ответ №1:
Выравнивание заключается в сопоставлении вложенных «сложных» объектов со свойствами на «более высоком» уровне, т. Е. в вашем случае, если CreateSelectionCommand
бы у вас было свойство Selection
типа, у которого было Name
свойство, оно было бы сопоставлено SelectionName
с типом назначения (см. this fiddle ).
Вы можете попробовать использовать префиксы, добавив:
cfg.RecognizePrefixes("Selection");
для вашей конфигурации (см. Эту Скрипку), но я сомневаюсь, что это подходящий вариант для обработки на основе соглашений.
Также кажется, что вы можете добавить пользовательское соглашение об именах, используя ISourceToDestinationNameMapper
и AddMemberConfiguration
:
class TypeNamePrefixedSourceToDestinationNameMapper : ISourceToDestinationNameMapper
{
public MemberInfo GetMatchingMemberInfo(IGetTypeInfoMembers getTypeInfoMembers, TypeDetails typeInfo,
Type destType,
Type destMemberType, string nameToSearch)
{
return getTypeInfoMembers.GetMemberInfos(typeInfo)
.FirstOrDefault(mi => mi.Name == destType.Name nameToSearch);
}
}
var config = new MapperConfiguration(cfg =>
{
cfg.AddMemberConfiguration().AddName<TypeNamePrefixedSourceToDestinationNameMapper>();
// ...
}
По крайней мере, это работает в этом простом случае, см. Эту скрипку.
Комментарии:
1. Хорошее объяснение и предложения. Я посмотрю, как далеко я смогу продвинуться с этим съездом. В противном случае я буду придерживаться явного определения сопоставления
2. @BorisCallens был рад помочь! Также я смог сделать что-то подобное (но выглядящее немного более хакерским), добавив некоторые сопоставления свойств
cfg.ForAllMaps
.