2015-03-18 6 views
0

Приложение, в котором я работаю, имеет несколько мест, где мы используем AutoMapper для сопоставления объектов.Забывание сопоставления классов с помощью AutoMapper

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

Он просто запускает приложение без полной функциональности и отладочных сообщений, что затрудняет определение того, что я пропустил.

Есть ли способ заставить компилятор во время компиляции дать мне ошибку в случае, если я забуду сделать сопоставление?

ответ

1

AFAIK, нет возможности принудительно проверять время компиляции для Automapper. Тем не менее, есть возможность проверить правильность ваших отображений: После того как вы определили все ваши отображения, вызовите AssertConfigurationIsValid метода, который будет выбрасывает AutoMapperConfigurationException исключения, если определенные отображения сломаны.

Вы можете сделать это частью вашего устройства или набора тестов интеграции.

+0

Некоторые люди также делают это во время запуска приложения, AssertConfigurationIsValid. –

+0

Это не решит проблему, если я забуду отобразить 2 объекта. потому что все остальные сопоставления действительны ..... –

+0

Даже не во время выполнения проблемы решает проблему ... –

0

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

Это может привести к снижению простоты внедрения AutoMapper, но я считаю, что проверка времени компиляции стоит того.

public class MyType { 
    public string SomeProperty { get;set; } 
} 

public class MyOtherType { 
    public string SomeProperty { get;set; } 
} 

public class MyAlternateType { 
    public string AlternateProperty {get;set;} 
} 

public class AutoMapperProfile : Profile { 
    public AutoMapperProfile() { 
     CreateMap<MyType, MyOtherType>(); 
     CreateMap<MyAlternateType, MyOtherType>() 
      .ForMember(ot => ot.SomeProperty, options => options.MapFrom(at => at.AlternateProperty)); 
    } 
} 

public interface IMyMappingProvider { 
    // Uncomment below for Queryable Extensions 
    //IQueryable<TDestination> ProjectTo<TSource, TDestination>(IQueryable<TSource> source, params Expression<Func<TDestination, object>>[] membersToExpand); 
    //IQueryable<TDestination> ProjectTo<TSource, TDestination>(IQueryable<TSource> source, IDictionary<string, object> parameters, params string[] membersToExpand); 

    /* 
    * Add your mapping declarations below 
    */ 

    MyOtherType MapToMyOtherType(MyType source); 
    MyOtherType MapToMyOtherType(MyAlternateType source); 
} 

public class MyMappingProvider : IMyMappingProvider { 
    private IMapper Mapper { get; set; } 

    public MyMappingProvider(IMapper mapper) { 
     Mapper = mapper; 
    } 

    /* Uncomment this for Queryable Extensions 
    public IQueryable<TDestination> ProjectTo<TSource, TDestination>(IQueryable<TSource> source, params Expression<Func<TDestination, object>>[] membersToExpand) { 
     return new ProjectionExpression(source, Mapper.ConfigurationProvider.ExpressionBuilder).To<TDestination>(null, membersToExpand); 
    } 

    public IQueryable<TDestination> ProjectTo<TSource, TDestination>(IQueryable<TSource> source, IDictionary<string, object> parameters, params string[] membersToExpand) { 
     return new ProjectionExpression(source, Mapper.ConfigurationProvider.ExpressionBuilder).To<TDestination>(parameters, membersToExpand); 
    } 
    */ 

    /* 
    * Implement your mapping methods below 
    */ 

    public MyOtherType MapToMyOtherType(MyType source) { 
     return Mapper.Map<MyType, MyOtherType>(source); 
    } 

    public MyOtherType MapToMyOtherType(MyAlternateType source) { 
     return Mapper.Map<MyAlternateType, MyOtherType>(source); 
    } 
} 

Если вы используете расширения запрашиваемых в AutoMapper в вы можете добавить следующий класс и раскомментировать код запрашиваемых Extensions выше.

public static class QueryableExtensions { 
    /* 
    * Implement your extension methods below 
    */ 
    public static IQueryable<MyOtherType> ProjectToMyOtherType(this IQueryable<MyType> source, IMyMappingProvider mapper, params Expression<Func<MyOtherType, object>>[] membersToExpand) 
    { 
     return mapper.ProjectTo<MyType, MyOtherType>(source, membersToExpand); 
    } 

    public static IQueryable<MyOtherType> ProjectToMyOtherType(this IQueryable<MyAlternateType> source, IMyMappingProvider mapper, params Expression<Func<MyOtherType, object>>[] membersToExpand) 
    { 
     return mapper.ProjectTo<MyAlternateType, MyOtherType>(source, membersToExpand); 
    } 
} 

Испытано с AutoMapper 6.1.1 с помощью LINQPad:

var autoMapperConfig = new MapperConfiguration(cfg => { cfg.AddProfile(new AutoMapperProfile()); }); 

IMyMappingProvider mapper = new MyMappingProvider(autoMapperConfig.CreateMapper()); 

var myTypes = new List<MyType>() 
{ 
    new MyType() {SomeProperty = "Test1"}, 
    new MyType() {SomeProperty = "Test2"}, 
    new MyType() {SomeProperty = "Test3"} 
}; 

myTypes.AsQueryable().ProjectToMyOtherType(mapper).Dump(); 

var myAlternateTypes = new List<MyAlternateType>() 
{ 
    new MyAlternateType() {AlternateProperty = "AlternateTest1"}, 
    new MyAlternateType() {AlternateProperty = "AlternateTest2"}, 
    new MyAlternateType() {AlternateProperty = "AlternateTest3"} 
}; 

myAlternateTypes.AsQueryable().ProjectToMyOtherType(mapper).Dump(); 

mapper.MapToMyOtherType(myTypes[0]).Dump(); 

Как @ serge.karalenka сказал, не забудьте еще проверить конфигурацию отображения, вызвав AssertConfigurationIsValid().

Смежные вопросы