3

I need to create a mapping (using AutoMapper) from n classes all being derived from one abstract class to a contract class

So for example:

public abstract class bar
{
   public string Field1 {get; set;}       
   public someClass Field2 {get; set;}
}

public class foo1bar: bar
{
 // members
}

public class foo2bar: bar
{
 // members
}

public class barContract
{
  public string Field1 {get; set;}

  // this will use existing someClass.Description field
  public string Field2Description {get; set;} 
}

implementations of bar class are multiple, and also are likely to change (more will be added). As Automapper cannot map to abstract class (so the constructor mapperConfiguration.CreateMap<bar, barContract>() is incorrect), I was wondering will it be possible to use reflection to find all classes 'implementing' bar class and map them 'automatically'

 var type = typeof(bar);
            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(s => s.GetTypes())
                .Where(p => type.IsAssignableFrom(p));

I've got the Types, and I'm trying to invoke CreateMap. As the type is now a variable, I'm creating a generic method once again using reflection:

foreach (Type t in types)
{
mapperConfiguration.GetType().GetMethod("CreateMap")
              .MakeGenericMethod(t, typeof(barContract))
              .Invoke(mapperConfiguration, null);
}

The problem is that CreateMap is not a member of type that is extracted from mapperConfiguration instance - when I'm trying to extract the method by name I get null. I see it's defined in IProfileExpression, so I'm trying to extract the method from the interface: typeof(IProfileExpression).GetMethod("CreateMap") and I get System.Reflection.AmbiguousMatchException - what is kind of OK, but using System.Reflection.BindingFlags in GetMethod to be more specific I'm again getting nulls.

What am I doing wrong, or how to get around that mapping problem ?

1 Answer 1

4

You can create map from one type to another type CreateMap(SouceType, DestinationType));

public abstract class Bar
{
    public string Field1 { get; set; }
}

public class Foo1bar : Bar
{
    // members
}

public class Foo2bar : Bar
{
    // members
}

public class BarContract
{
    public string Field1 { get; set; }

    // this will use existing someClass.Description field
    public string Field2Description { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        AutoMapperConfiguration.Init();

        var foo1 = new Foo1bar {Field1 = "One"};
        var barContract1=AutoMapperConfiguration.Mapper.Map<Foo1bar, BarContract>(foo1);
        Console.WriteLine("barContract1.Field1: " + barContract1.Field1);

        var foo2 = new Foo2bar {Field1 = "Two"};
        var barContract2=AutoMapperConfiguration.Mapper.Map<Foo2bar, BarContract>(foo2);
        Console.WriteLine("barContract2.Field1: " + barContract2.Field1);

        Console.ReadLine();
    }

    public static class AutoMapperConfiguration
    {
        public static void Init()
        {
            MapperConfiguration = new MapperConfiguration(cfg =>
            {
                var types = Assembly.GetExecutingAssembly().GetTypes()
                    .Where(type => !string.IsNullOrEmpty(type.Namespace) &&
                                    type.BaseType != null &&
                                    type.BaseType == typeof(Bar));
                foreach (Type type in types)
                {
                    cfg.CreateMap(type, typeof(BarContract));
                }
            });

            Mapper = MapperConfiguration.CreateMapper();
        }

        public static IMapper Mapper { get; private set; }

        public static MapperConfiguration MapperConfiguration { get; private set; }
    }
}

Output

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.