2016-07-11 32 views
15

Non riesco a capire come utilizzare la nuova interfaccia IValueResolver nella nuova versione di AutoMapper. Forse li ho usati in modo improprio nelle precedenti versioni di AutoMapper ...Come utilizzare il nuovo IValueResolver di AutoMapper?

Ho un sacco di classi di modelli, alcuni dei quali sono generati da diversi database su diversi server di database, utilizzando sqlmetal.

Alcune di queste classi hanno una proprietà stringa, PublicationCode, che identifica la pubblicazione dell'abbonamento, dell'offerta, o della fattura, o qualunque essa sia, a cui appartiene.

La pubblicazione può esistere in uno dei due sistemi (il vecchio e il nuovo sistema), quindi ho una proprietà bool sulle classi del modello di destinazione che indica se la pubblicazione è nel vecchio o nel nuovo sistema.

Utilizzando la vecchia versione (< 5?) Di automapper, ho usato una ValueResolver<string, bool> che ha preso la PublicationCode come parametro di input, e ha restituito un bool che indica la posizione della pubblicazione (sistema di vecchio o nuovo).

Con la nuova versione (5+?) Di AutoMapper, questo sembra non essere più possibile. Il nuovo IValueResolver richiede un'implementazione unica di ogni singola combinazione di modelli di origine e di destinazione, laddove src.PublicationCode deve essere risolto in un dst.IsInNewSystem.

Sto solo cercando di utilizzare i risolutori di valori nel modo sbagliato? C'è un modo migliore? Il motivo principale per cui vorrei utilizzare un resolver è che preferirei avere servizi iniettati nel costruttore e non dover usare DependencyResolver e simili nel codice (sto usando Autofac).

Attualmente, lo uso nel modo seguente:

// Class from Linq-to-SQL, non-related properties removed. 
public class FindCustomerServiceSellOffers { 
    public string PublicationCode { get; set; } 
} 

Questa è una delle diverse classi del modello di dati che ho, che contiene una proprietà PublicationCode). Questa classe particolare è mappato questo modello vista:

public class SalesPitchViewModel { 
    public bool IsInNewSystem { get; set; } 
} 

La definizione di mappatura per queste due classi è (in cui espressione è un IProfileExpression), non sono collegati mappature rimossi:

expression.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>() 
      .ForMember(d => d.IsInNewSystem, o => o.ResolveUsing<PublicationSystemResolver>().FromMember(s => s.PublicationCode)); 

E resolver:

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); 
    } 
} 

E l'uso del mapper:

var result = context.FindCustomerServiceSellOffers.Where(o => someCriteria).Select(_mapper.Map<SalesPitchViewModel>).ToList(); 
+0

Fine. Ho aggiunto un codice un po 'laconico per mostrare come attualmente utilizzo AutoMapper. – PaddySe

risposta

5

È possibile creare un resolver di valori più generale implementando IMemberValueResolver<object, object, string, bool> e utilizzarlo nella configurazione di mapping. È possibile fornire una funzione di risoluzione delle proprietà di origine come prima:

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

Cercando di costruire un dotnetfiddle pienamente funzionante ma non è gradito il pacchetto nuget AutoMapper – Rhumborl

+0

Oh bello, non ho nemmeno visto quell'interfaccia. Ho implementato i tuoi suggerimenti su tutti i miei risolutori, ma ora ho qualche strana eccezione su op_Equality, e mentre penso che riguardi l'aggiornamento di AutoMapper, probabilmente non è correlato a questa particolare domanda. Grazie mille per il tuo aiuto!! – PaddySe

+0

@Rhumborl Ho fatto esattamente la stessa cosa della tua risposta, ma la mia classe resolver non è mai stata colpita da un breakpoint. Qualche idea? Posso creare un repository se vuoi esaminarlo. Grazie. – Robin