omu.valueinjecter 深度克隆不同类型 [英] omu.valueinjecter deep clone unlike types
问题描述
我想我缺少 valueinjecter 和/或 AutoMapper 的一个简单概念,但是您如何将父 dto.Entity 深度克隆到 biz.Entity 并包括所有子项?
I think I'm missing a simple concept with valueinjecter and/or AutoMapper, but how do you deep clone a parent dto.Entity to biz.Entity and include all children?
例如,biz.person.InjectFrom(dto.person)
.我希望 dto.person.AddressList 集合向下复制到 biz.person.AddressList 集合,即使 dto.Address
和 biz.Address
是不同的类型,但有相同的属性名称.
For example, biz.person.InjectFrom(dto.person)
. I want the dto.person.AddressList collection to copy down to biz.person.AddressList collection, even though dto.Address
and biz.Address
are unlike types, but have the same property names.
我的想法是,如果父属性名称拼写相同,例如AddressList,那么 2 个底层对象是否属于不同类型都无关紧要.它仍然会复制同名的简单类型,如 int、string 等.
My thinking is that if the Parent property names are spelled the same, e.g. AddressList, then it wouldn't matter if the 2 underlying objects were of different types. It would still copy same-named simple types like int, string, etc.
谢谢
推荐答案
当对象中的数组/列表具有相同的名称但类型不同(即类型为 ORMAnimals[] 映射的名为 Animals 的属性时,我遇到了同样的问题到类型为 Animals[] 的名为 Animals 的属性).
I was having the same issue when the arrays/lists in the objects have the same names but different types (ie a property named Animals of type ORMAnimals[] mapping to a property named Animals of type Animals[]).
对 Chuck Norris 在 Deep Cloning 页面上的示例代码进行了一些小的调整 我在我的测试代码中得到了它:
With some minor tweaks to the sample code Chuck Norris has on the Deep Cloning page I got it working 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);
}
}
这篇关于omu.valueinjecter 深度克隆不同类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!