Omu.valueinjecter deep clone unlike types

I think I am missing a simple concept with a valueinjecter and / or AutoMapper, but how do you deeply clone the parent dto.Entity for biz.Entity and include all children?

For example, biz.person.InjectFrom(dto.person) . I want the dto.person.AddressList collection to copy to the biz.person.AddressList collection, although dto.Address and biz.Address do not look like types but have the same property names.

My thinking is that if the names of the properties of the parent are written the same way, for example, AddressList, then it would not matter if the 2 base objects have different types. It will still copy the same simple types like int, string, etc.

Thank you

+7
source share
1 answer

I had the same problem when arrays / lists in objects had the same names but different types (ie the "Animals type ORMAnimals []" property displaying the "Animals type animals" [] property).

With some minor changes to the sample code of Chuck Norris on the Deep Cloning page, I got it in my test code:

 public class CloneInjection : ConventionInjection { protected override bool Match(ConventionInfo c) { return c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Value != null; } protected override object SetValue(ConventionInfo c) { //for value types and string just return the value as is if (c.SourceProp.Type.IsValueType || c.SourceProp.Type == typeof(string) || c.TargetProp.Type.IsValueType || c.TargetProp.Type == typeof(string)) return c.SourceProp.Value; //handle arrays if (c.SourceProp.Type.IsArray) { var arr = c.SourceProp.Value as Array; var clone = Activator.CreateInstance(c.TargetProp.Type, arr.Length) as Array; for (int index = 0; index < arr.Length; index++) { var a = arr.GetValue(index); if (a.GetType().IsValueType || a.GetType() == typeof(string)) continue; clone.SetValue(Activator.CreateInstance(c.TargetProp.Type.GetElementType()).InjectFrom<CloneInjection>(a), index); } return clone; } if (c.SourceProp.Type.IsGenericType) { //handle IEnumerable<> also ICollection<> IList<> List<> if (c.SourceProp.Type.GetGenericTypeDefinition().GetInterfaces().Contains(typeof(IEnumerable))) { var t = c.TargetProp.Type.GetGenericArguments()[0]; if (t.IsValueType || t == typeof(string)) return c.SourceProp.Value; var tlist = typeof(List<>).MakeGenericType(t); var list = Activator.CreateInstance(tlist); var addMethod = tlist.GetMethod("Add"); foreach (var o in c.SourceProp.Value as IEnumerable) { var e = Activator.CreateInstance(t).InjectFrom<CloneInjection>(o); addMethod.Invoke(list, new[] { e }); // in 4.0 you can use dynamic and just do list.Add(e); } return list; } //unhandled generic type, you could also return null or throw return c.SourceProp.Value; } //for simple object types create a new instace and apply the clone injection on it return Activator.CreateInstance(c.TargetProp.Type) .InjectFrom<CloneInjection>(c.SourceProp.Value); } } 
+7
source

All Articles