AutoMapper: map interface with abstract class - is this possible?

I use AutoMapper to map objects between different layers of my application. On the one hand, I have an interface that looks like this:

public interface MyRepo { IEnumerable<IRootObject> GetItems(param); } 

IRootObject is as follows:

 public interface IRootObject { int Id { get; set; } DateTime? Date { get; set; } } public interface IFirstSubObject : IRootObject { string MyFirstProp { get; set; } } public interface ISecondSubObject : IRootObject { string MySecondProp { get; set; } } 

So calling GetItems() actually returns an array of only IxxxSubObjectItems . On the other hand, the structure is as follows:

 public abstract class MyCustomRoot { protected MyCustomRoot(){} public int Id { get; set; } public DateTime? Date { get; set; } } public class MyCustomFirstSub : MyCustomRoot { public MyCustomFirstSub() : base() {} public string MyFirstProp { get; set; } } public class MyCustomSecondSub : MyCustomRoot { public MyCustomSecondSub () : base() {} public string MySecondProp { get; set; } } 

Now I configured mapper like this

 AutoMapper.Mapper.CreateMap<IRootObject, MyCustomRoot> .Include<IFirstSubObject, MyCustomFirstSub> .Include<ISecondSubObject, MyCustomSecondSub>(); AutoMapper.Mapper.CreateMap<IFirstSubObject, MyCustomFirstSub>(); AutoMapper.Mapper.CreateMap<ISecondSubObject, MyCustomSecondSub>(); 

But I keep getting MapperExceptions ("Cannot construct an abstract class", which makes sense in some way). I also call AssertConfigurationIsValid and this passes this code.
If I do not do an abstract abstraction of MyCustomRoot , then the mapping works, but I get a list of MyCustomRoot objects, while I really would like to have a list of MyCustomxxxSub , because there is a Factory later on which this type is used to generate the correct user interface ...

Hope someone can point me in the right direction for this! Thank you

+4
source share
2 answers

Ok, I found a way to actually do this! So, with the interfaces and classes above, you can do something like this
(Remember: MyCustomRoot class MyCustomRoot abstract)

 AutoMapper.Mapper.CreateMap<IRootObject, MyCustomRoot> .Include<IFirstSubObject, MyCustomFirstSub> .Include<ISecondSubObject, MyCustomSecondSub>(); 

and then use the following Map Map call to map the objects:

 public List<MyCustomRoot> PerformMapping(List<IRootObject> rootObjects) { var returnList = new List<CustomRoot>(); foreach(var rootObject in rootObjects) { var abstractObject = (MyCustomRoot)Mapper.Map(rootObject, rootObject.GetType(), typeof(MyCustomRoot)); returnList.Add(abstractObject); } return returnList; } 

Now I get an array of MyCustomRoot objects, which are all specific implementations.

This is exactly what I was looking for!

+7
source

If this is the case, then you want to map the factory to this, enter it and give it the opportunity to create the correct instance at the appointed time, since it is a factory that apparently knows what to create.

0
source

Source: https://habr.com/ru/post/1347059/


All Articles