I am trying to deep clone the following class using 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;
}
}
The Clone
method works fine for the MainData properties but seems to only do a shallow copy of the Details list. I have tried adding .ForMember(d => d.Details, o => o.UseDestinationValue())
but this does not copy the Details list at all. How can I get the Details list deep cloned as well ie, so I end up with two totally independent objects including all the list items?
UPDATE: I need to exclude the Id property as I am using these objects with NHibernate so not sure if the Serializable solution will do this.
UPDATE2: Modified the above code to clone the IList too. This seems to work fine as I can exclude properties that make NHibernate think it has already been saved.
AutoMapper isn't really a cloning API. I would instead use this cloning trick:
It doesn't work for every situation, but it's pretty handy.
here is one solution with the ValueInjecter
the properties that have private setters are not going to be set, (looks reasonable)
good luck ;)
EDIT: I did a better solution look here