2016-07-11 5 views
15

Я в затруднении относительно того, как использовать новый интерфейс IValueResolver в новой версии AutoMapper. Возможно, я неправильно использовал их в предыдущих версиях AutoMapper ...Как использовать новый IValueResolver AutoMapper?

У меня много классов моделей, некоторые из них генерируются из нескольких баз данных на нескольких серверах баз данных, используя sqlmetal.

Некоторые из этих классов имеют свойство string, PublicationCode, которое определяет, к какой публикации относится подписка, предложение или счет-фактура или что-то еще.

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

Используя старую версию (< 5?) Из AutoMapper, я использовал ValueResolver<string, bool> который принял PublicationCode в качестве входного параметра, и возвратил bool указания места публикации (старая или новая система).

С новой версией AutoMapper (5+?) Это кажется невозможным. Новый 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(); 
+0

Выполнено. Я добавил несколько краткий код, чтобы показать, как я использую AutoMapper. – PaddySe

ответ

5

Вы можете создать более общий преобразователь значения путем реализации 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)); 
+0

Попытка построить полностью рабочий dotnetfiddle, но он не нравится пакет AutoMapper nuget – Rhumborl

+0

О, круто, даже не видел этого интерфейса. Я внедрил ваши предложения обо всех моих решениях, но теперь у меня есть странное исключение из op_Equality, и, хотя я думаю, что это связано с обновлением AutoMapper, это, вероятно, не связано с этим конкретным вопросом. Большое спасибо за Вашу помощь!! – PaddySe

+0

@Rhumborl Я сделал то же самое, что и ваш ответ, но мой класс resolver никогда не попал в точку останова. Есть идеи? Я могу создать репо, если вы хотите изучить его. Благодарю. – Robin