4

我正在尝试使用 ValueInjector 来展平一个类,并让它也跨值从Nullable<int>'sto复制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;
    }
}

基本上我想将两者结合起来。这可能吗?

4

3 回答 3

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 行)

于 2012-04-18T07:33:28.773 回答
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);
于 2019-10-16T17:55:08.633 回答
-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;
    }
}
于 2016-02-04T11:40:05.810 回答