Как использовать новый IValueResolver AutoMapper?
Я не понимаю, как использовать новый интерфейс IValueResolver
в новой версии AutoMapper. Возможно, я неправильно использовал их в предыдущих версиях AutoMapper...
У меня много классов моделей, некоторые из них генерируются из нескольких баз данных на нескольких серверах баз данных, используя sqlmetal.
Некоторые из этих классов имеют свойство string, PublicationCode
, которое определяет, к какой публикации относится подписка или предложение, или счет-фактура или что-то еще.
Публикация может существовать в любой из двух систем (старой и новой системы), поэтому у меня есть свойство bool на классах целевых моделей, которые указывают, является ли публикация старой или новой.
Используя старую версию (<5?) AutoMapper, я использовал ValueResolver<string, bool>
который принял PublicationCode
в качестве входного параметра и возвратил bool
указывающий местоположение публикации (старая или новая система).
С новой версией (5+?) AutoMapper это кажется более невозможным. Новый IValueResolver требует уникальной реализации каждой комбинации исходных и целевых моделей, которые у меня есть, где src.PublicationCode
необходимо разрешить в dst.IsInNewSystem
.
Я просто пытаюсь использовать преобразователи ценности не так? Есть ли способ лучше? Основная причина, по которой я хотел бы использовать резольвер, - это то, что я предпочел бы, чтобы сервисы были введены в конструктор, и не нужно использовать DependencyResolver
и тому подобное в коде (я использую Autofac).
В настоящее время я использую его следующим образом:
// Class from Linq-to-SQL, non-related properties removed.
public class FindCustomerServiceSellOffers {
public string PublicationCode { get; set; }
}
Это один из нескольких классов модели данных, которые у меня есть, который содержит свойство PublicationCode). Этот конкретный класс сопоставляется с этой моделью представления:
public class SalesPitchViewModel {
public bool IsInNewSystem { get; set; }
}
Определение отображения для этих двух классов (где выражение является выражением IProfileExpression), несвязанные сопоставления удалены:
expression.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>()
.ForMember(d => d.IsInNewSystem, o => o.ResolveUsing<PublicationSystemResolver>().FromMember(s => s.PublicationCode));
И резольвер:
public class PublicationSystemResolver : ValueResolver<string, bool>
{
private readonly PublicationService _publicationService;
public PublicationSystemResolver(PublicationService publicationService)
{
_publicationService = publicationService;
}
protected override bool ResolveCore(string publicationCode)
{
return _publicationService.IsInNewSystem(publicationCode);
}
}
И использование картографа:
var result = context.FindCustomerServiceSellOffers.Where(o => someCriteria).Select(_mapper.Map<SalesPitchViewModel>).ToList();
Ответы
Ответ 1
Вы можете создать более общий преобразователь значений, IMemberValueResolver<object, object, string, bool>
и используя это в вашей конфигурации сопоставления. Вы можете предоставить функцию разрешения исходного свойства, как и раньше:
public class PublicationSystemResolver : IMemberValueResolver<object, object, string, bool>
{
private readonly PublicationService _publicationService;
public PublicationSystemResolver(PublicationService publicationService)
{
this._publicationService = publicationService;
}
public bool Resolve(object source, object destination, string sourceMember, bool destMember, ResolutionContext context)
{
return _publicationService.IsInNewSystem(sourceMember);
}
}
cfg.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>()
.ForMember(dest => dest.IsInNewSystem,
src => src.ResolveUsing<PublicationSystemResolver, string>(s => s.PublicationCode));