Играя с ASP.Net MVC 3 и изучая его, я работал с AutoMapper для сопоставления сущностей моего домена с моими моделями представления.
Я устал от индивидуального создания картыдля каждой ViewModel я реализовал.В результате я написал некоторый код для сканирования моей сборки и использовал некоторое отражение для создания каждого из необходимых отображений.Однако, поскольку я не очень хорошо знаком с лучшими практиками использования AutoMappers, я подумал, что смогу показать всем, что я сделал, и спросить, может ли мой подход вернуться назад, чтобы укусить меня.
По сути, яиметь класс с именем AutoMappingConfigurator (используется в Global.asax.cs) следующим образом:
public static class AutoMappingConfigurator
{
public static void Configure(Assembly assembly)
{
var autoMappingTypePairingList = new List<AutoMappingTypePairing>();
foreach (Type t in assembly.GetTypes())
{
var autoMapAttribute = t
.GetCustomAttributes(typeof(AutoMapAttribute), true)
.OfType<AutoMapAttribute>()
.FirstOrDefault();
if (autoMapAttribute != null)
{
autoMappingTypePairingList
.Add(new AutoMappingTypePairing(autoMapAttribute.SourceType, t));
}
}
autoMappingTypePairingList
.ForEach(mappingPair => mappingPair.CreateBidirectionalMap());
}
}
По сути, он выполняет сканирование сборки для всех типов, помеченных с помощью AutoMapAttribute, и для каждого из них.обнаруживается, что он создает двунаправленное отображение.
AutoMapAttribute - это простой атрибут, который я создал (основываясь на примерах, которые я нашел в Интернете), который я присоединяю к своей модели представления, чтобы указать, к какому объекту домена он привязан..
Например.
[AutoMap(typeof(Project))]
public class ProjectDetailsViewModel
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Что касается двунаправленного отображения, до сих пор в моей работе с MVC3 я обнаружил, что мне часто кажется, что мне нужно сопоставить Entity с ViewModel дляHttpGet и из ViewModel в Entity для HttpPost.
Двунаправленное отображение реализуется какметод расширения следующим образом:
public static void CreateBidirectionalMap(this AutoMappingTypePairing mappingPair)
{
Mapper.CreateMap(mappingPair.SourceType, mappingPair.DestinationType)
.IgnoreProperties(mappingPair.DestinationType);
Mapper.CreateMap(mappingPair.DestinationType, mappingPair.SourceType)
.IgnoreProperties(mappingPair.SourceType);
}
Что касается метода расширения IgnoreProperties, я обнаружил, что всякий раз, когда у меня была модель представления, у которой было свойство, которое я хотел игнорировать (например, когда моя модель представления имеет раскрывающийся список, которыйне является частью базового доменного объекта) Мне, кажется, пришлось создать игнорирование вручную с помощью метода ForMember AutoMapper.Поэтому я создал еще один атрибут, чтобы указать, какие свойства нужно было игнорировать, чтобы мой код отражения в AutoMappingConfigurator мог сделать это для меня автоматически.
Метод расширения IgnoreProperties реализован как метод расширения следующим образом:
public static IMappingExpression IgnoreProperties(this IMappingExpression expression
, Type mappingType)
{
var propertiesWithAutoMapIgnoreAttribute =
mappingType.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(AutoMapIgnoreAttribute), true)
.OfType<AutoMapIgnoreAttribute>()
.Count() > 0);
foreach (var property in propertiesWithAutoMapIgnoreAttribute)
{
expression.ForMember(property.Name, opt => opt.Ignore());
}
return expression;
}
Все это позволяет мне написать мою ViewModel следующим образом и иметь ее AutoMapped:
[AutoMap(typeof(EntityClass))]
private class ViewModelClass
{
public int EntityClassId { get; set; }
[AutoMapIgnore]
public IEnumerable<SelectListItem> DropDownItems { get; set; }
}
private class EntityClass
{
public int EntityClassId { get; set; }
}
Пока это работает для меня до сих пор, я боюсь, что он может вернуться, чтобы укусить меня из-замой низкий уровень опыта работы с AutoMapper.
Итак, мои вопросы:
- Это хороший способ настроить AutoMapper для настройки моих сопоставлений между моими сущностями домена и моделями представления?
- Есть ли что-то в AutoMapper, которое я могу пропустить, что сделает это плохим подходом?
- Является ли хорошей идеей подключение свойства Игнорировать по отражению и атрибутам?
- Является ли создание двунаправленной карты между моей сущностью и ViewModel хорошей идеей?