Chris Hawkes
Chris Hawkes

Reputation: 12410

How to map this using automapper?

I will be upfront by saying I just started using AutoMapper. I'm having some problems understanding if what I'm trying to do is incorrect.

I have an abstract class.

 public abstract class Animal
    {
        public int Age { get; set; }
    }

I have a class that derives from this abstract class

 public class Cat : Animal
    {
        public string Name { get; set; }

        public string Type { get; set; }
    }

I have a separate class that shares values that need to be mapped to the Cat class derived from the Animal abstract class.

 public class ProblemClass
    {
        public string Name { get; set; }
    }

I have a mapper setup like so,

Mapper.CreateMap<ProblemClass, Animal>();

I've instantiated a ProblemClass item.

var problemClass = new ProblemClass();
Mapper.Map<Animal>(problemClass);

How would I go about mapping something like this? My main point of confusion is is automapper obviously cannot instantiate an abstract class, so I'm really confused how to create a generic Mapper for Animal which works with all kinds of animal sub classes derived from it.

Upvotes: 1

Views: 90

Answers (1)

Alexei - check Codidact
Alexei - check Codidact

Reputation: 23078

A possible solution is to create mappings between your source type and all derived destination types automatically:

using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public abstract class Animal
        {
            public int Age { get; set; }
        }

        public class Cat : Animal
        {
            public string Name { get; set; }

            public string Type { get; set; }
        }

        public class ProblemClass
        {
            public string Name { get; set; }
        }

        private static IList<Type> GetAllDerivedTypes(Type t)
        {
            var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
                            from assemblyType in domainAssembly.GetTypes()
                            where t.IsAssignableFrom(assemblyType)
                            select assemblyType);
            return listOfBs.ToList();
        }

        private static void MapAllTypes(Type srcType, Type destType)
        {
            var allDestTypes = GetAllDerivedTypes(destType);
            foreach (var destTypeDerived in allDestTypes)
            {
                Mapper.CreateMap(srcType, destTypeDerived);
            }
        }

        static void Main(string[] args)
        {
            MapAllTypes(typeof(ProblemClass), typeof(Animal));

            var problemClass = new ProblemClass() { Name = "test name" };
            Animal someAnimal = new Cat();

            // after this (someAnimal as Cat).Name will be "test name"
            Mapper.Map(problemClass, someAnimal);
        }
    }
}

Upvotes: 1

Related Questions