Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ValueInjecter to flatten objects including nullable types

I'm trying to use ValueInjector to flatten a class and to have it also copy across values from Nullable<int>'s to int's.

Eg given the following (contrived) classes:

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

I would like to flatten an instance of CustomerObject to a CustomerDTO, with it ignoring the fact that the CustomerID and OrderID's are of different types (one is nullable one isn't).

So I would like to do this:

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

And then have all of the properties populated, specifically:

customer.CustomerID 
customer.OrderOneOrderID 
customer.OrderOneOrderName

I realise I can use FlatLoopValueInjection to flatten out the object, and I'm using this NullableInjection class:

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

Basically I'd like to combine the two. Is this possible?

like image 503
Rocklan Avatar asked Feb 20 '23 19:02

Rocklan


1 Answers

you could do this by overriding the TypesMatch method:

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

or by grabbing the FlatLoopValueInjection from the source code and edit it as you need (it's about 10 lines)

like image 172
Omu Avatar answered Apr 26 '23 23:04

Omu