2011-01-14 20 views
8

Così ho due tipi complessi personalizzati come questo (troppo semplificata per questo esempio):Come convertire un tipo complesso personalizzato ad un altro tipo complesso personalizzato

public class PendingProduct 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public int ColorCount { get; set; } 
} 

Diciamo che ho bisogno di questo oggetto per sapere come convertire se stesso ad un altro tipo:

public class Product 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public ProductColors Colors { get; set;} 
} 

Così, quando chiamo un metodo per convertire PendingProduct al prodotto, io eseguire una logica personalizzata che aggiunge "Conteggio a colori" numero di oggetti ProductColor alla classe del prodotto. Questo è totalmente semplificato, ma l'architettura della classe è davvero irrilevante qui.

Che la mia domanda principale è, è questa:

Qual è il metodo migliore prassi da utilizzare per attuare la conversione di un tipo complesso ad un altro tipo complesso quando le proprietà degli oggetti differiscono?

Nel mondo reale, le proprietà sono molto diverse e sarò scrivere una logica personalizzata per mappare quello che mi serve da Object A alla B. Object

Ovviamente ho potuto solo scrivere una funzione che prende un parametro di input dell'oggetto A e restituisce l'oggetto B, ma sto cercando un metodo più "Best Practice". IConvertible entra in gioco qui? C'è qualcosa di più simile a OOP di cui posso approfittare piuttosto che scrivere una funzione per fare ciò che voglio?

oggetto A dovrebbe sempre sapere come convertire stesso per l'oggetto B.

EDIT: Come nota a margine, nel mondo reale, oggetto A e B sono entrambi oggetto Entity Framework 4 entità. Voglio prendere un "Prodotto in attesa", convertirlo in una nuova entità prodotto, collegarlo al contesto dati e salvare.

risposta

18

Ci sono molti modi in cui questo può essere fatto, ma si riducono davvero a scrivere il codice di mappatura da soli, gestendolo attraverso la riflessione, o basandosi su un framework pre-costruito come AutoMapper. Ho risposto a una domanda simile in un'altra domanda SO here.

aggiungerò qui per il vostro riferimento:

Realisticamente si potrebbe

1.Reflection

public void Map<TSource, TDestination>(TSource source, TDestination destination) 
{ 
    var props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance); 
    var type = typeof(TDestination); 

    foreach (var prop in props) 
    { 
    object value = prop.GetValue(source, null); 

    var prop2 = type.GetProperty(prop.Name); 
    if (prop2 == null) 
     continue; 

    if (prop.PropertyType != prop2.PropertyType) 
     continue; 

    prop2.SetValue(destination, value, null); 
    } 
} 

2.Copia Constructor

public Employee(Person person) 
{ 
    // Copy properties 
} 

3.Implicit/Conversione esplicita

public static implicit operator Employee(Person person) 
{ 
    // Build instance and return 
} 

4.AutoMapper

Mapper.Map<Person, Employee>(person); 

5.Combination di 3/4:

public static implicit operator Employee(Person person) 
{ 
    return Mapper.Map<Person, Employee>(person); 
} 

Una nota su operatori di conversione implicito/esplicito: credo nell'uso di questi non sarà generando Codice conforme a CLS.

automapper non consente di personalizzare la modalità diverse proprietà sul tipo di destinazione vengono mappati sopra, ad es .:

Mapper.CreateMap<Person, Employee>() 
     .ForMember(e => e.Forename, o => o.MapFrom(p => p.Forename.ToLower())); 
0

non si vorrebbe derivare da PendingProduct prodotto?

public class Product 
{  
    public string Name { get; set; }  
    public string Description { get; set; }  
    public ProductColors Colors { get; set; } 
} 

public class PendingProduct : Product 
{   
    public int ColorCount { get; set; } 
} 
Problemi correlati