У меня была такая же проблема, и я решил решить эту проблему, обернув 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().
Некоторые люди также делают это во время запуска приложения, AssertConfigurationIsValid. –
Это не решит проблему, если я забуду отобразить 2 объекта. потому что все остальные сопоставления действительны ..... –
Даже не во время выполнения проблемы решает проблему ... –