【问题标题】:Steps to map classes using ValueInjector使用 ValueInjector 映射类的步骤
【发布时间】:2012-10-08 08:12:35
【问题描述】:

快速解决以下代码未发生映射的问题。有人可以解释为什么吗?或者我应该怎么做才能进行映射?

var parent = new Parent();
parent.ChildOne.Add(new ChildOne() { Name = "Child One" });
parent.ChildTwo.Add(new ChildTwo() { Name = "Child Two" });
AnotherParent anotherParent = new AnotherParent();

anotherParent.InjectFrom<LoopValueInjection>(parent);

必修课如下

另一个孩子

 public class AnotherChildOne
    {
        public string Name { get; set; }
    }

另一个孩子两个

 public class AnotherChildTwo
    {
        public string Name { get; set; }

    }

另一个家长

public class AnotherParent
    {
        public ICollection<AnotherChildOne> ChildOne { get; set; }

        public ICollection<AnotherChildTwo> ChildTwo { get; set; }

        public AnotherParent()
        {
            ChildOne = new Collection<AnotherChildOne>();
            ChildTwo = new Collection<AnotherChildTwo>();
        }


    }

孩子二

public class ChildTwo
    {
        public string Name { get; set; }

    }

孩子一

 public class ChildOne
    {
        public string Name { get; set; }
    }

家长

 public class Parent
    {

        public ICollection<ChildOne> ChildOne { get; set; }

        public ICollection<ChildTwo> ChildTwo { get; set; }

        public Parent()
        {
            ChildOne = new Collection<ChildOne>();
            ChildTwo = new Collection<ChildTwo>();
        }

    }

【问题讨论】:

    标签: collections mapping valueinjecter


    【解决方案1】:

    我相信默认情况下,Value Injector 只会注入具有相同名称的相同类型的属性。您可以通过调整 Value Injector 文档中的 CloneInjection 示例来解决此问题,如here 所述,使用以下代码:

    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);
        }
    }
    

    如果您包含上述CloneInjection 代码,您将需要这样做:

    anotherParent.InjectFrom<CloneInjection>(parent);
    

    代替:

    anotherParent.InjectFrom<LoopValueInjection>(parent);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      • 2016-06-12
      • 2023-03-17
      • 2018-07-05
      • 2020-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多