Skip to content

Specs v2 #2

@aoancea

Description

@aoancea

In v2 we are reviewing how Map works as in v1 it was deep copying all the object apart from the root reference

namespace Runtime.Mapper
{
    public class Cow
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public Mule Mule { get; set; }
    }

    public class Mule
    {
        public Guid Id { get; set; }

        public DateTime BirthDate { get; set; }
    }

    public class Program
    {
        static ConcurrentDictionary<Tuple<Type, Type>, Func<object, object, object>> mappingFunctions = new ConcurrentDictionary<Tuple<Type, Type>, Func<object, object, object>>();

        static int Main(string[] args)
        {
            mappingFunctions.GetOrAdd(new Tuple<Type, Type>(typeof(Cow), typeof(Cow)), (s, d) => { return Map_Cow(s, d); });
            mappingFunctions.GetOrAdd(new Tuple<Type, Type>(typeof(Mule), typeof(Mule)), (s, d) => { return Map_Mule(s, d); });


            Cow cow = new Cow();
            cow.Id = Guid.NewGuid();
            cow.Name = "Cow 1";
            cow.Mule = new Mule() { Id = Guid.NewGuid(), BirthDate = new DateTime(2017, 01, 01) };

            Cow destination = cow.DeepCopyTo<Cow>();  // deep copy 'cow'


            Cow source = new Cow();
            source.Id = Guid.NewGuid();
            source.Name = "Cow 2";
            source.Mule = new Mule() { Id = Guid.NewGuid(), BirthDate = new DateTime(2017, 02, 01) };

            Cow destination = new Cow();

            Map<Cow, Cow>(cow, destination);  // map 'source' into 'destination'
        }

        public static void Map<TSource, TDestination>(TSource source, TDestination destination)
        {
            Tuple<Type, Type> key = new Tuple<Type, Type>(typeof(TSource), typeof(TDestination));

            Func<object, object, object> mappingFunction = mappingFunctions[key];

            mappingFunction(source, destination); // Map_Cow(source, destination);
        }

        public static TDestination DeepCopyTo<TDestination>(this object source)
        {
            Tuple<Type, Type> key = new Tuple<Type, Type>(source.GetType(), typeof(TDestination));

            Func<object, object, object> mappingFunction = mappingFunctions[key]; // Map_Cow(source, null);

            return (TDestination)mappingFunction(source, null);
        }

        public static Cow Map_Cow(object sourceObj, object destinationObj)
        {
            if (sourceObj == null)
                return null;

            Cow source = (Cow)sourceObj;
            Cow destination = null;

            if (destinationObj == null)
                destination = new Cow();
            else
                destination = (Cow)destinationObj;

            destination.Id = source.Id;
            destination.Name = source.Name;

            Map<Mule, Mule>(source.Mule, destination.Mule);

            return destination;
        }

        public static Mule Map_Mule(object sourceObj, object destinationObj)
        {
            if (sourceObj == null)
                return null;

            Mule source = (Mule)sourceObj;
            Mule destination = null;

            if (destinationObj == null)
                destination = new Mule();
            else
                destination = (Mule)destinationObj;

            destination.Id = source.Id;
            destination.BirthDate = source.BirthDate;

            return destination;
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions