我正在尝试使用ValueInjector展平一个类,并让它复制从Nullable<int>'s
到int
的值。
例如给出以下(人为)类:
class CustomerObject
{
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public OrderObject OrderOne { get; set; }
}
class OrderObject
{
public int OrderID { get; set; }
public string OrderName { get; set; }
}
class CustomerDTO
{
public int? CustomerID { get; set; }
public string CustomerName { get; set; }
public int? OrderOneOrderID { get; set; }
public string OrderOneOrderName { get; set; }
}
我想将CustomerObject的实例展平为 一个CustomerDTO,它忽略了CustomerID的事实 和OrderID是不同类型的(一个是可空的,不是)。
所以我想这样做:
CustomerObject co = new CustomerObject() { CustomerID = 1, CustomerName = "John Smith" };
co.OrderOne = new OrderObject() { OrderID = 2, OrderName = "test order" };
CustomerDTO customer = new CustomerDTO();
customer.InjectFrom<>(co);
然后填充所有属性,具体为:
customer.CustomerID
customer.OrderOneOrderID
customer.OrderOneOrderName
我意识到我可以使用FlatLoopValueInjection
来展平对象,我正在使用这个NullableInjection类:
public class NullableInjection : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name &&
(c.SourceProp.Type == c.TargetProp.Type
|| c.SourceProp.Type == Nullable.GetUnderlyingType(c.TargetProp.Type)
|| (Nullable.GetUnderlyingType(c.SourceProp.Type) == c.TargetProp.Type
&& c.SourceProp.Value != null)
);
}
protected override object SetValue(ConventionInfo c)
{
return c.SourceProp.Value;
}
}
基本上我想把两者结合起来。这可能吗?
答案 0 :(得分:9)
你可以通过覆盖TypesMatch方法来实现这个目的:
public class MyFlatInj : FlatLoopValueInjection
{
protected override bool TypesMatch(Type sourceType, Type targetType)
{
var snt = Nullable.GetUnderlyingType(sourceType);
var tnt = Nullable.GetUnderlyingType(targetType);
return sourceType == targetType
|| sourceType == tnt
|| targetType == snt
|| snt == tnt;
}
}
或从源代码中获取FlatLoopValueInjection并根据需要进行编辑(大约10行)
答案 1 :(得分:0)
ValueInjecter V3删除FlatLoopValueInjection。以下是Omu的答案的更新。
public class FlatLoopInjectionNullable : Omu.ValueInjecter.Injections.FlatLoopInjection
{
protected override bool Match(string propName, PropertyInfo unflatProp, PropertyInfo targetFlatProp)
{
var snt = Nullable.GetUnderlyingType(unflatProp.PropertyType);
var tnt = Nullable.GetUnderlyingType(targetFlatProp.PropertyType);
return propName == unflatProp.Name
&& unflatProp.GetGetMethod() != null
&& (unflatProp.PropertyType == targetFlatProp.PropertyType
|| unflatProp.PropertyType == tnt
|| targetFlatProp.PropertyType == snt
|| (snt != null && snt == tnt));
}
}
这样称呼它:
target.InjectFrom<ValueInjecterNullable>(source);
答案 2 :(得分:-1)
// !!! THIS IS FOR LoopInjection not FlatLoopValueInjection !!!
public class NullableInjection : LoopInjection
{
public NullableInjection() : base() { }
public NullableInjection(string[] ignoredProps) : base(ignoredProps) { }
protected override bool MatchTypes(Type source, Type target)
{
// This is the most likely scenario test for it first.
bool result = source == target;
// if not a type match then lets do more expensive tests.
if (!result)
{
var snt = Nullable.GetUnderlyingType(source);
var tnt = Nullable.GetUnderlyingType(target);
// Make sure that underlying types have not reverted to null
// this will cause false positives.
result = ((source == target)
|| ((tnt != null) && source == tnt)
|| ((snt != null) && target == snt)
|| ((tnt != null) && snt == tnt));
}
return result;
}
}