2016-06-15 13 views
5

Sto utilizzando la seguente mappatura per mappare il mio oggetto dati sull'oggetto viewmodel.C# Automapper Come risolvere l'utilizzo della proprietà da customresolver

ObjectMapper.cs

public static class ObjectMapper 
{ 
    public static void Configure() 
    { 
     Mapper.CreateMap<User, UserViewModel>() 
      .ForMember(dest => dest.Title, 
         opt => opt.ResolveUsing<TitleValueResolver>()) 
      .ForMember(dest => dest.Name, 
         opt => opt.ResolveUsing<NameValueResolver >()) 
      .ForMember(dest => dest.ShortName, 
         opt => opt.ResolveUsing<ShortNameValueResolver >());   
    } 
} 

Parser

public class Parser{ 
public string GetTitle(string title){ 
/* add some logic */ 
return title; 
} 
public string GetName(string title){ 
/* add some logic */ 
return name; 
} 
public string GetShortName(string title){ 
/* add some logic */ 
return shortname; 
} 
} 

AutoMapperCustomResolvers.cs

public class TitleValueResolver : ValueResolver<User, string> 
{ 
    private readonly BaseValueResolver _baseResolver; 
    public TitleValueResolver() 
    { 
     _baseResolver = new BaseValueResolver(); 
    } 

    protected override string ResolveCore(Usersource) 
    { 
     return _baseResolver.Parser.GetTitle(source.TITLE); 
    } 
} 

public class NameValueResolver : ValueResolver<User, string> 
{ 
    private readonly BaseValueResolver _baseResolver; 
    public NameValueResolver() 
    { 
     _baseResolver = new BaseValueResolver(); 
    } 

    protected override string ResolveCore(Usersource) 
    { 
     return _baseResolver.Parser.GetName(source.TITLE); 
    } 
} 

public class ShortNameValueResolver : ValueResolver<User, string> 
{ 
    private readonly BaseValueResolver _baseResolver; 
    public ShortNameValueResolver() 
    { 
     _baseResolver = new BaseValueResolver(); 
    } 

    protected override string ResolveCore(Usersource) 
    { 
     return _baseResolver.Parser.GetShortName(source.TITLE); 
    } 
} 

Sto usando il codice qui sopra per aggiungere la logica per la proprietà di destinazione utilizzando il valore personalizzato separata risolutori. Non sono sicuro che questo sia l'approccio giusto.

i) Esiste un modo migliore per raggiungere questo obiettivo?

ii) E come utilizzare l'unità da risolvere nel caso in cui si desideri iniettare una dipendenza dal costruttore del resolver personalizzato?

Grazie

+0

Come ci si aspetta che 'TitleValueResolver' sia costruito? Non ha un costruttore predefinito e non si fornisce un'espressione 'ConstructedBy' per la propria configurazione di mapping. In generale, il tuo esempio è severamente privo di classi ...per favore riduci o fornisci i pezzi mancanti per trasformare il tuo esempio in un ruolo. – grek40

+0

@ grek40, ho aggiornato la mia domanda. –

+0

'TypeValueResolver' è il nuovo' TitleValueResolver'? Come ti aspetti che un risolutore di valori per 'MAMAsset' risolva qualcosa che proviene dal tipo' Utente'? – grek40

risposta

0

Come ho capito la tua domanda, si vuole utilizzare un ValueResolver, che risolve più proprietà di origine in un oggetto di dati intermedio, che viene utilizzato per risolvere i più proprietà di destinazione. Per fare un esempio, mi assumo le seguenti origine, destinazione, i tipi di intermedi e resolver:

// source 
class User 
{ 
    public string UserTitle { get; set; } 
} 

// target 
class UserViewModel 
{ 
    public string VM_Title { get; set; } 

    public string VM_OtherValue { get; set; } 
} 

// intermediate from ValueResolver 
class UserTitleParserResult 
{ 
    public string TransferTitle { get; set; } 
} 

class TypeValueResolver : ValueResolver<User, UserTitleParserResult> 
{ 
    protected override UserTitleParserResult ResolveCore(User source) 
    { 
     return new UserTitleParserResult { TransferTitle = source.UserTitle }; 
    } 
} 

Hai bisogno di un proprietà target al fine di utilizzare opt.ResolveUsing<TypeValueResolver>(). Ciò significa che è possibile stabilire una mappatura in cui è disponibile una proprietà target appropriata.

Quindi, per il momento, lascia avvolgere il risultato in un adeguato tipo di contenitore:

class Container<TType> 
{ 
    public TType Value { get; set; } 
} 

E creare una mappatura

Mapper.CreateMap<User, Container<UserViewModel>>() 
    .ForMember(d => d.Value, c => c.ResolveUsing<TypeValueResolver>()); 

E un'altra mappatura

Mapper.CreateMap<UserTitleParserResult, UserViewModel>() 
    .ForMember(d => d.VM_Title, c => c.MapFrom(s => s.TransferTitle)) 
    .ForMember(d => d.VM_OtherValue, c => c.Ignore()); 

E un altro mapping

Mapper.CreateMap<User, UserViewModel>() 
    .BeforeMap((s, d) => 
    { 
     Mapper.Map<User, Container<UserViewModel>>(s, new Container<UserViewModel> { Value = d }); 
    }) 
    .ForAllMembers(c => c.Ignore()); 
// establish more rules for properties... 

L'ultimo mapping è un po 'speciale, poiché si basa su una mappatura nidificata per aggiornare la destinazione con i valori dalla sorgente tramite regole di mappatura configurate separatamente. È possibile avere più mapping di trasferimento diversi per proprietà diverse aggiungendo mapping e chiamate intermedie appropriate in BeforeMap del tipo mappato effettivo. Le proprietà che vengono gestiti in altre mappature devono essere ignorati, in quanto automapper non conosce la mappatura in BeforeMap

Piccolo esempio di utilizzo:

var user = new User() { UserTitle = "User 1" }; 

// create by mapping 
UserViewModel vm1 = Mapper.Map<UserViewModel>(user); 

UserViewModel vm2 = new UserViewModel() { VM_Title = "Title 2", VM_OtherValue = "Value 2" }; 
// map source properties into existing target 
Mapper.Map(user, vm2); 

so se questo ti aiuta. Ci potrebbero essere modi migliori se riformuli la tua domanda per descrivere il tuo problema iniziale invece di ciò che sospetti di essere una soluzione.

+0

ho aggiornato la mia domanda. Spero che sarà chiaro ora. –

+0

Siamo spiacenti, Unity è fuori dal mio scopo, non l'ho ancora usato. – grek40

+0

Ciao, in sostanza sto cercando di usare ValueResolver che risolve su una singola proprietà sorgente in un oggetto intermedio che risolverà più proprietà di destinazione. –

Problemi correlati