AutoMapper передает родительскую ссылку при отображении дочернего объекта - PullRequest
4 голосов
/ 17 марта 2011

Я пытаюсь использовать AutoMapper для сопоставления некоторых объектов DTO (контракт данных), полученных от веб-службы, с моими бизнес-объектами.Корневой объект DTO содержит коллекцию дочерних объектов.Мой бизнес-объект также имеет дочернюю коллекцию дочерних бизнес-объектов.Чтобы заставить AutoMapper работать, мне нужно было включить установщик в свойстве коллекции в моем бизнес-объекте, иначе коллекция всегда будет пустой.Кроме того, мне пришлось добавить конструктор по умолчанию в тип коллекции.Итак, мне кажется, что AutoMapper создает экземпляр нового объекта коллекции, заполняет его и устанавливает в качестве свойства коллекции моего бизнес-объекта.

Хотя это все хорошо, у меня есть дополнительная логика, которая должна бытьподключен при создании коллекции и имеет конструктор по умолчанию, побеждающий цель.По сути, я устанавливаю отношения родитель-потомок и подключаю некоторые события, чтобы они пузырились от потомка к родителю.

Я хотел бы, чтобы AutoMapper просто отобразил дочерние объекты из коллекции DTO насуществующая коллекция на моем БО.Другими словами, пропустите создание новой коллекции и просто используйте ту, которая уже есть в бизнес-объекте.

Есть ли способ легко выполнить это?!?!?

ОБНОВЛЕНИЕ

Возможно, лучший вопрос и более простое решение моей проблемы: возможно ли определить аргументы, которые AutoMapper будет передавать в коллекцию при создании экземпляра?Моя дочерняя коллекция определяется следующим образом:

public class ChildCollection : Collection<ChildObjects>
{
    public ChildCollection(ParentObject parent) { Parent = parent; }
}

Если я могу настроить AutoMapper на использование этого конструктора и передать соответствующий объект, это будет ИДЕАЛЬНО!

ДРУГОЕ ОБНОВЛЕНИЕ

Для ясности, вот другие классы в проблемном пространстве:

public class ParentObject
{
    private ChildCollection _children;

    public ChildCollection Children
    {
        get
        {
            if (_children == null) _children = new ChildCollection(this);

            return _children;
        }
    }
}

public class ParentDTO
{
    public ICollection<ChildDTO> Children { get; set; }
}

public class ChildDTO
{
    public String SomeProperty { get; set; }
}

Я настраиваю AutoMapper следующим образом:

Mapper.CreateMap<ParentDTO, ParentObject>();
Mapper.CreateMap<ChildDTO, ChildObject>();

Делая тактаким образом, и я должен добавить установщик в свойство Children в ParentObject и конструктор по умолчанию (без параметров) для ChildCollection.Хотя я могу обойти необходимость определения отношения родитель-потомок, представляется логичным ожидать, что AutoMapper будет поддерживать настройку карты для использования определенного конструктора при создании дочерней коллекции.Примерно так:

Mapper.CreateMap<ParentDTO, ParentObject>()
    .ForMember(obj => obj.Children, opt.MapFrom(dto => dto.Children))
    .ConstructUsing(col => new ChildCollection(obj));

Обратите внимание, что я передаю ссылку на "obj", который является отображаемым экземпляром ParentObject.

Ответы [ 2 ]

7 голосов
/ 24 марта 2011

Оказывается, ответ был тут же все время. Опция UseDestinationValue делает именно то, что я хочу.

Этот параметр указывает AutoMapper использовать существующее свойство целевого объекта и сопоставлять любые дочерние свойства или элементы коллекции с этим объектом вместо создания нового прокси-объекта.

Итак, вот все, что я должен сделать в своем приложении:

Mapper.CreateMap<ParentDTO, ParentObject>()
    .ForMember(obj => obj.Children,
           opt.UseDestinationValue());

И, вуаля! Теперь я могу создать экземпляр дочерней коллекции со ссылкой на родителя и установить ссылку на родителя в каждом элементе по мере его добавления в коллекцию.

0 голосов
/ 17 марта 2011

Если я понял вашу проблему, вы сможете использовать ConstructUsing, как указано в этом ответе: Automapper - как сопоставить параметры конструктора вместо установщиков свойств

...