Automapper: лучшие практики для ReverseMap - PullRequest
0 голосов
/ 10 января 2020

Я ищу некоторые рекомендации по использованию ReverseMap при настройке сопоставлений для Automapper.

Я использую Automapper для сопоставления между объектами БД и моими моделями. Для ясности, вот упрощенный пример того, как они выглядят:

public class Document
{
    public string Id { get; set; }
    public List<Element> Elements { get; set; }
}

public class Element
{       
    public string Name { get; set; }       
        public virtual ElementType Type { get; set; }
}

public class ElementText : Element
{      
        public string Value { get; set; }      
        public Hashtable Attributes { get; set; }      
        public override ElementType Type { get; set; }
}


public class DocumentModel
{
        public string Id { get; set; }
        public List<ElementModel> Elements { get; set; }    
}

public class ElementModel
{       
    public string Name { get; set; }       
    public virtual ElementType Type { get; }
}

public class ElementTextModel : ElementModel
{
        public string Value { get; set; }
        public Hashtable Attributes { get; set; }
        public override ElementType Type { get { return ElementType.TEXT; } }
}

Таким образом, классы Document являются первичными классами и хранят списки элементов и производные классы от Element, такие как ElementText, в списке элементов.

Профиль сопоставления:

 public MappingProfile()
        {

            this.CreateMap<Document, DocumentModel>().ReverseMap();
            this.CreateMap<Element, ElementModel>().ReverseMap();
            this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
        }

Теперь этот профиль работает в большинстве случаев, но не может отобразить производные классы в списке. Вместо этого он сопоставляет их с базовым классом. (Таким образом, элементы ElementText становятся Element, et c)

Я могу это исправить, используя IncludeAllDerived в профиле, например так:

 public MappingProfile()
        {

            this.CreateMap<Document, DocumentModel>().ReverseMap();
            this.CreateMap<Element, ElementModel>()
                 .IncludeAllDerived()
                 .ReverseMap();

            this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
        }

Но, похоже, порядок .IncludeAllDerived ( ) и .ReverseMap () имеют значение. И единственный способ заставить производные классы работать в обоих направлениях - это использовать:

 public MappingProfile()
        {

            this.CreateMap<Document, DocumentModel>().ReverseMap();
            this.CreateMap<Element, ElementModel>()
                 .IncludeAllDerived()
                 .ReverseMap().IncludeAllDerived();

            this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
        }

, который начинает немного неуклюже на мой вкус. Я предпочел бы отказаться от ReverseMap и явно определить отображение для обоих направлений.

 public MappingProfile()
        {

            this.CreateMap<Document, DocumentModel>().ReverseMap();
            this.CreateMap<Element, ElementModel>()
                 .IncludeAllDerived()
            this.CreateMap<ElementModel, Element>()
                 .IncludeAllDerived();

            this.CreateMap<ElementText, ElementTextModel>().ReverseMap();
        }

Итак, мой вопрос, когда мне следует использовать ReverseMap? Никогда? Только в очень простых случаях?

Дает ли явное указание отображения в обоих направлениях один и тот же результат? Документация немного неясна, за исключением поста с инструкциями по использованию здесь Джимми говорит:

X AVOID ReverseMap в случаях, кроме случаев, когда сопоставляются только не сплющенные свойства верхнего уровня

Обратное сопоставление может очень быстро усложниться, и, если оно не очень простое, в конфигурации сопоставления могут отображаться бизнес-логи c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...