2015-05-07 1 views
3

У меня есть служба, которая обертывает значения enum в типе SafeEnum, чтобы включить добавление новых значений перечисления без нарушения контракта.Использование AutoMapper для отображения Wrapper to T 'по соглашению

Вот пример:

public class Customer 
{ 
    public int Id { get; set; } 
    public SafeEnum<CustomerType> Type { get; set; } 
} 

public class CustomerModel 
{ 
    public int Id { get; set; } 
    public CustomerModelType Type { get; set; } 
} 

Когда отображение Клиента CustomerModel с использованием AutoMapper, есть способ автоматической карты от SafeEnum<T> к T', где T является завернутым типом и T' это тип соответствия в модель?

Я знаю, что это можно исправить, настроив для каждого соответствующего типа перечисления, но я ищу более элегантное решение.

+0

@zespri Нет, это модельная версия CustomerType, то есть другой тип перечисления с такими же или подобными значениями. Я отредактировал этот пример, чтобы отразить это, спасибо, что указали это. (пример - всего лишь пример, он не отражает реальные типы, которые у меня есть) – martinnjensen

ответ

0

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

Сначала вам нужно создать класс, который реализует интерфейс IObjectMapper. Этот интерфейс имеет два метода IsMatch(ResolutionContext context) и Map(ResolutionContext context, IMappingEngineRunner mapper)

При отображении двух объектов, метод IsMatch используются внутри Automapper, чтобы определить, является ли данный экземпляр IObjectMapper может быть использован для отображения от типа источника к типу назначения. На объекте ResolutionContext у вас есть SourceType, DestinationType, SourceValue, DestinationValue, экземпляр MappingEngine, среди прочего, который может помочь вам определить, можете ли вы сопоставить два типа с вашим текущим картографом.

Метод Map отвечает за фактическое сопоставление между двумя типами.

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

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

Наконец, вам нужно включить этот картограф при настройке MappingEngine при запуске приложения (это не работает со статическим методом класса Mapper, так как вы не можете изменить его по умолчанию), например это:

var configuration = new ConfigurationStore(new TypeMapFactory(), new IObjectMapper[] { new WrapperMapper()}.Union(MapperRegistry.Mappers)); 
     var engine = new MappingEngine(configuration);  

MapperRegistry.Mappers статическое свойство представляет собой совокупность всех картографов Automapper по умолчанию. Если вы не включите их, вы потеряете все функциональные возможности по умолчанию.

Наконец, вот рабочая скрипку: https://dotnetfiddle.net/vWmRiY

Это, вероятно, потребуется некоторая работа, чтобы адаптировать его к конкретному прецеденту, но общая идея есть.Это можно использовать для обертывания примитивных типов, сложных типов или всего, что поддерживается automapper.