I have an object which contains two different object types, I am trying to map it to another object which will contain a single list.
In this simple minimal reproducible example I have created a zoo class which contains a list of animals this is the destination. The source is the MammelHouse class which contains lists of pig and cow objects.
My issue is when I try to add the pigs to the list then it over writes the already written cows. I need both objects to be added to this list.
My current solution is to map each object type alone and then add them to the main object, as my actual application has ten different types currently this is not an optimal solution. I am hoping that there is a way to solve this with automapper directly.
current mapping attempt
public class MappingResourceZoo : Profile
{
public MappingResourceZoo()
{
CreateMap<MammalHouse, Zoo>()
.ForMember(dest => dest.Animals, opt => opt.MapFrom(src => src.Cows))
.ForMember(dest => dest.Animals, opt => opt.MapFrom(src => src.Pigs));
CreateMap<Cow, Animal>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Species));
CreateMap<Pig, Animal>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Species));
}
}
The issue with this mapping is that when pigs are mapped the cows are over written. So the test fails.,
Test
[Fact]
public void TestsConcatAddress()
{
var src = new MammalHouse()
{
Cows = new List<Cow>()
{
new Cow() {Species= "Chocolate cow"},
new Cow() {Species= "Vanilla cow"}
},
Pigs = new List<Pig>()
{
new Pig() { Species= "Bacon"},
new Pig() { Species= "Sausage"}
}
};
var config = new MapperConfiguration(cfg => cfg.AddProfile<MappingResourceZoo>());
var mapper = config.CreateMapper();
var response = mapper.Map<Zoo>(src);
response.Animals.Should().NotBeNull().And.HaveCount(4); ;
}
Here is the model for your testing pleasure. These two models can not be altered as they come from a third party system.
// The Zoo model comes from third party api 1
public class Zoo
{
public List<Animal> Animals { get; set; }
}
public class Animal
{
public string Name { get; set; }
}
// The mammal model comes from third party api Two.
public class MammalHouse
{
public List<Cow> Cows { get; set; }
public List<Pig> Pigs { get; set; }
}
public class Cow
{
public string Species{ get; set; } = "cow";
}
public class Pig
{
public string Species{ get; set; } = "pig";
}
What i have looked at
- Add AfterMap This doesn't seam to be the right direction as i actually have more then just two.
- Currently trying to get it to work using a custom mapper but that doesn't seam to work either as i cant pass it the mapper object.
update from comments
From the comment suggested apparently Concat isnt allowed.
CreateMap<MammalHouse, Zoo>()
.ForMember(dest => dest.Animals, opt => opt.MapFrom(src => src.Cows.Concat(src.Pigs)));
Tried add range as well this doent work either becouse cows and pigs are not the same type
opt.MapFrom(src => src.Cows.AddRange(src.Pigs)));