Как использовать новый 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));