Use AutoMapper to map an interface to a specific type

I created dotNetFiddle which demonstrates the question here .


Here is a simplified example of what I'm trying to do ... let's say I have the following interfaces:

public interface IPerson { int Id { get; set; } } public interface IModelPerson : IPerson { int BeautyCompetitionsWon { get; set; } } 

In a real implementation, there are many different types of people (e.g., IUglyPerson , etc.). These are contracts for entity types, for example. in the following way:

 public class PersonEntity : IPerson { public int Id { get; set; } } public class ModelPersonEntity : PersonEntity, IModelPerson { public int BeautyCompetitionsWon { get; set; } } 

Note We can also have several implementations of each type of contract - for example, IModelPerson can also be implemented by SupermodelEntity .

We want to map our entity types to DTOs that look something like this:

 public abstract class PersonDto : IPerson { public int Id { get; set; } public abstract string PersonType { get; } } public class ModelPersonDto : PersonDto, IModelPerson { public int BeautyCompetitionsWon { get; set; } public override string PersonType { get { return "Model"; } } } 

Thus, we create a mapping:

 Mapper.Initialize(config => { config.CreateMap<IPerson, PersonDto>() .Include<IModelPerson, ModelPersonDto>() .ConstructUsing((IPerson person) => { if (person is IModelPerson) return new ModelPersonDto(); throw new InvalidOperationException("Unknown person type: " + person.GetType().FullName); }) ; config.CreateMap<IModelPerson, ModelPersonDto>(); }); 

So, I have two questions.

1. Is there a way to create mappings without a ConstructUsing clause? I thought a more specific version of CreateMap took care of this for us, but if I don't have ConstructUsing , AutoMapper tells me: "Instances of abstract classes cannot be created."

2. Why properties from my subclasses are not displayed? If I perform the mapping as follows:

 var source = new ModelPersonEntity { Id = 100, BeautyCompetitionsWon = 9 }; var target = Mapper.Map<PersonDto>(source); 

The expected value for target.BeautyCompetitionsWon is 9, but the actual value is 0.

+7
c # automapper
source share
1 answer

Question 1: Not what I know.

Question 2: When using .ConstructUsing (), make sure you return the displayed object, not a new instance.

eg.

 Mapper.Initialize(config => { config.CreateMap<IPerson, PersonDto>() .Include<IModelPerson, ModelPersonDto>() .ConstructUsing((IPerson person) => { if (person is IModelPerson) return Mapper.Map<ModelPersonDto>(person); throw new InvalidOperationException("Unknown person type: " + person.GetType().FullName); }) ; config.CreateMap<IModelPerson, ModelPersonDto>(); }); 
+7
source share

All Articles