I'm using AutoMapper to map objects between different layers of my application. On the one side I have an interface which looks like this:
public interface MyRepo
{
IEnumerable<IRootObject> GetItems(param);
}
IRootObject looks like this:
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 the GetItems()
call actually returns an array of only IxxxSubObjectItems
.
On the other side the structure looks like this:
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've set up the mapper like so
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 abstract class", which makes sense in a way). I also call AssertConfigurationIsValid
, and that passes for this code.
If I don't make the MyCustomRoot
class abstract, then the mapping works, but I get a list of MyCustomRoot
objects, while I actually would like to have a list of MyCustomxxxSub
, because there is a Factory later on which uses this type to generate the correct UI...
I hope someone can point me in the right direction for this one!
Thanks!
Ok I found a way to actually do this!
So with the Interfaces and Classes provided above, you can do something like this
(Remember: the MyCustomRoot
class is abstract)
AutoMapper.Mapper.CreateMap<IRootObject, MyCustomRoot>
.Include<IFirstSubObject, MyCustomFirstSub>
.Include<ISecondSubObject, MyCustomSecondSub>();
and then use the followig 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 actually get an array of MyCustomRoot
objects, which are all the specific implementations.
This is exactly what I was looking for!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With