ValueInjecter我如何将代码从V2.4更新到V3.2,没有约定注入



我正在将一个应用程序从net框架升级到.net核心3.0。我使用的是windows presentation foundation Wpf,我想在其最新版本3.2中实现ValueInjecter…该应用程序目前运行在ValueInjector的2.4版本上,请提供帮助!。网上没有太多的文档。这个代码看起来怎么样?My CloneInjection.cs:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Omu.ValueInjecter;
namespace Infrastructure.Data.Injection
{
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))
return c.SourceProp.Value;
//handle arrays
if (c.SourceProp.Type.IsArray)
{
var arr = c.SourceProp.Value as Array;
var clone = arr.Clone() as Array;
for (int index = 0; index < arr.Length; index++)
{
var a = arr.GetValue(index);
if (a.GetType().IsValueType || a is string) continue;
clone.SetValue(Activator.CreateInstance(a.GetType()).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.SourceProp.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.SourceProp.Type)
.InjectFrom<CloneInjection>(c.SourceProp.Value);
}
}
}

我的EntityInjection.cs:

using System.Collections;
using System.Diagnostics;
using System.Linq;
using Omu.ValueInjecter;
namespace Infrastructure.Data.Injection
{
public class EntityInjection : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
var propertyMatch = c.SourceProp.Name == c.TargetProp.Name;
var sourceNotNull = c.SourceProp.Value != null;
bool targetPropertyIdWritable = !(propertyMatch && c.TargetProp.Name == "Id" && !(c.Target.Value is IEntityClass));
return propertyMatch && sourceNotNull && targetPropertyIdWritable;
}
protected override object SetValue(ConventionInfo c)
{
if (c.SourceProp.Type.IsValueType || c.SourceProp.Type == typeof(string))
return c.SourceProp.Value;
if (c.SourceProp.Type.IsGenericType)
{
var td = c.SourceProp.Type.GetGenericTypeDefinition();
if (td != null && td.GetInterfaces().Contains(typeof(IEnumerable)))
{
var targetChildType = c.TargetProp.Type.GetGenericArguments()[0];
if (targetChildType.IsValueType || targetChildType == typeof(string)) return c.SourceProp.Value;
if (targetChildType.GetInterfaces().Any(x => x == typeof(IValueClass)))
{
var deleteMethod = c.TargetProp.Value.GetType().GetMethod("Remove");
var rmvItems = (c.TargetProp.Value as IEnumerable).Cast<IValueClass>()
.Where(x => x.Id > 0 && !(c.SourceProp.Value as IEnumerable).Cast<IValueClass>().Any(y => y.Id == x.Id));
rmvItems.ToList().ForEach(x => deleteMethod.Invoke(c.TargetProp.Value, new[] { x }));
rmvItems = (c.TargetProp.Value as IEnumerable).Cast<IValueClass>()
.Where(x => !(c.SourceProp.Value as IEnumerable).Cast<IValueClass>().Contains(x));
rmvItems.ToList().ForEach(x => deleteMethod.Invoke(c.TargetProp.Value, new[] { x }));
var sourceCollection = (c.SourceProp.Value as IEnumerable).Cast<IValueClass>();
foreach (var s in sourceCollection)
{
var sv = s;
var target = (c.TargetProp.Value as IEnumerable).Cast<IValueClass>().SingleOrDefault(z => z.Id == sv.Id && z.Id != 0);
if (target != null) target.InjectFrom<EntityInjection>(sv);
else if (!(c.TargetProp.Value as IEnumerable).Cast<IValueClass>().Contains(sv))
{
if (!(sv is IEntityClass))
{
sv = Activator.CreateInstance(targetChildType) as IValueClass;
Debug.Assert(sv != null);
sv.InjectFrom<EntityInjection>(s);
sv.Id = 0;
}
var addMethod = c.TargetProp.Value.GetType().GetMethod("Add");
addMethod.Invoke(c.TargetProp.Value, new[] { sv });
}
}
}
}
return c.TargetProp.Value;
}
if (c.SourceProp.Value is IEntityClass)
{
return c.SourceProp.Value;
}
if (c.TargetProp.Value == null)
{
try
{
c.TargetProp.Value = Activator.CreateInstance(c.TargetProp.Type);
}
catch (Exception)
{
return null;
}
}
return c.TargetProp.Value.InjectFrom<EntityInjection>(c.SourceProp.Value);
}
}
}

如果你不能切换到LoopInjection,你也可以尝试将这个类添加到你的项目中:

public abstract class ConventionInjection : ValueInjection
{
protected abstract bool Match(ConventionInfo c);
protected virtual object SetValue(ConventionInfo c)
{
return c.SourceProp.Value;
}
protected override void Inject(object source, object target)
{
var sourceProps = source.GetProps();
var targetProps = target.GetProps();
var ci = new ConventionInfo
{
Source =
{
Type = source.GetType(), 
Value = source
},
Target =
{
Type = target.GetType(),
Value = target
}
};
for (var i = 0; i < sourceProps.Count; i++)
{
var s = sourceProps[i];
ci.SourceProp.Name = s.Name;
ci.SourceProp.Value = s.GetValue(source);
ci.SourceProp.Type = s.PropertyType;
for(var j=0; j < targetProps.Count; j++)
{
var t = targetProps[j];
ci.TargetProp.Name = t.Name;
ci.TargetProp.Value = t.GetValue(target);
ci.TargetProp.Type = t.PropertyType;
if (Match(ci))
t.SetValue(target, SetValue(ci));
}
}
}
}
public class ConventionInfo
{
public ConventionInfo()
{
Source = new TypeInfo();
Target = new TypeInfo();
SourceProp = new PropInfo();
TargetProp = new PropInfo();
}
public TypeInfo Source { get; set; }
public TypeInfo Target { get; set; }
public PropInfo SourceProp { get; set; }
public PropInfo TargetProp { get; set; }
public class PropInfo
{
public string Name { get; set; }
public Type Type { get; set; }
public object Value { get; set; }
}
public class TypeInfo
{
public Type Type { get; set; }
public object Value { get; set; }
}
}

最新更新