2010-08-03 10 views
13

Sto cercando di profondo clone della classe seguente utilizzando automapper:Come oggetti clone profonde che contengono una proprietà IList utilizzando automapper

public class MainData 
{ 
    public MainData() 
    { 
     Details = new List<Detail>(); 
    } 

    public int Id { get; private set; } 
    public DateTime LastUpdate { get; private set; } 
    public IList<Detail> Details { get; private set; } 
    public int Prop1 { get; set; } 
    public int Prop2 { get; set; } 

    public void AddDetail(Detail detail) 
    { 
     Details.Add(detail); 
    } 

    public void RemoveDetail(Detail detail) 
    { 
     Details.Remove(detail); 
    } 

    public MainData Clone() 
    { 
     Mapper.Reset(); 
     Mapper.CreateMap<MainData, MainData>().ForMember(d => d.Id, o => o.Ignore()); 
     // Mapper.CreateMap<Detail, Detail>().ForMember(d => d.Id, o => o.Ignore()); // REMOVED 
     var newMainData = new MainData(); 
     Mapper.Map(this, newMainData); 
     newMainData.Details = this.Details.Select(item => item.Clone()).ToList(); // ADDED 
     return newMainData; 
    } 
} 

public class Detail 
{ 
    public int Id { get; private set; } 
    public string Name { get; set; } 
    public double Area { get; set; } 
    public double Height { get; set; } 

    public Detail Clone() // ADDED 
    { 
     Mapper.CreateMap<Detail, Detail>().ForMember(d => d.Id, o => o.Ignore()); 
     var newDetail = new Detail(); 
     Mapper.Map(this, newDetail); 
     return newDetail; 
    } 
} 

Il metodo Clone funziona bene per le proprietà MAINDATA ma sembra di fare solo una copia della lista Dettagli. Ho provato ad aggiungere .ForMember(d => d.Details, o => o.UseDestinationValue()) ma questo non copia affatto l'elenco Dettagli. Come posso ottenere anche la clonazione profonda dell'elenco Dettagli, quindi alla fine ho due oggetti totalmente indipendenti che includono tutte le voci dell'elenco?

UPDATE: Ho bisogno di escludere la proprietà Id mentre sto usando questi oggetti con NHibernate, quindi non sono sicuro se la soluzione Serializable farà questo.

UPDATE2: È stato modificato il codice precedente per clonare anche IList. Questo sembra funzionare bene in quanto posso escludere proprietà che fanno pensare a NHibernate che sia già stato salvato.

risposta

9

qui è una soluzione con i ValueInjecter

 var clone = new MainData(); 

     clone.InjectFrom(mainData);//mainData is your source 

     mainData.Details.AsParallel.ForAll(detail => 
     { 
      var dc = new Detail(); 
      dc.InjectFrom(detail); 
      clone.AddDetail(dc); 
     }); 

le proprietà che hanno setter privati ​​non stanno per essere impostato, (sembra ragionevole)
buona fortuna;)

EDIT: ho fatto una soluzione migliore look here

+0

Molto bella la biblioteca, funziona bene. Ho dovuto cambiare la parte PLINQ in un ciclo ForEach perché non sto ancora utilizzando .NET 4. –

+0

@Pers Myers, ho fatto qualcosa di più generico per la clonazione, puoi vederlo qui http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu

+0

grazie per l'aggiornamento, lo controllerò. –

9

AutoMapper non è realmente un'API di clonazione. Vorrei invece usare questo trucco di clonazione:

public static object CloneObject(object obj) 
{ 
    using (MemoryStream memStream = new MemoryStream()) 
    { 
     BinaryFormatter binaryFormatter = new BinaryFormatter(null, 
      new StreamingContext(StreamingContextStates.Clone)); 
     binaryFormatter.Serialize(memStream, obj); 
     memStream.Seek(0, SeekOrigin.Begin); 
     return binaryFormatter.Deserialize(memStream); 
    } 
} 

Non funziona per tutte le situazioni, ma è piuttosto utile.

+0

grazie, ho trovato questa soluzione alcune volte nella mia ricerca ma non ero sicuro di voler rendere tutte le mie classi serializzabili. Il metodo di Automapper sembrava abbastanza elegante se riesco a farlo funzionare come voglio io. –

+0

questo è un trucco popolare per la clonazione. sfortunatamente introduce tutti i tipi di problemi legati alla serializzazione/deserializzazione. Speravo che anche AutoMapper fosse più diretto :) –

Problemi correlati