使用AutoMapper从接口映射到具体类型 [英] Use AutoMapper to map from an interface to a concrete type
问题描述
这是我要执行的操作的简化示例……假设我具有以下接口:
Here's a simplified example of what I'm trying to do... let's say I have an the following interfaces:
public interface IPerson
{
int Id { get; set; }
}
public interface IModelPerson : IPerson
{
int BeautyCompetitionsWon { get; set; }
}
在实际的实现中,有很多不同类型的人(例如IUglyPerson
等).这些是实体类型的合同,例如如下:
In the real implementation, there are lots of different types of people (e.g. IUglyPerson
, etc). These are the contracts for entity types, e.g. as follows:
public class PersonEntity : IPerson
{
public int Id { get; set; }
}
public class ModelPersonEntity : PersonEntity, IModelPerson
{
public int BeautyCompetitionsWon { get; set; }
}
注意:对于每种合同类型,我们可能还会有多种实现方式-例如IModelPerson
也可以由SupermodelEntity
实现.
Note: We may also have multiple implementations of each contract type - e.g. IModelPerson
may also be implemented by SupermodelEntity
.
我们想将实体类型映射到DTO,如下所示:
We want to map our entity types to DTOs, which 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"; }
}
}
因此,我们创建了一个映射:
As such, 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 issues here.
1.有没有办法创建没有ConstructUsing
子句的映射?我以为拥有更具体版本的CreateMap
会为我们解决这个问题,但是如果我没有
1. Is there any way of creating the mappings without the ConstructUsing
clause? I thought that having the more specific version of CreateMap
would have taken care of this for us, but if I don't have the ConstructUsing
clause, AutoMapper tells me "Instances of abstract classes cannot be created".
2.为什么我的子类中的属性未映射?如果我按如下所示执行映射:
2. Why don't the properties from my subclasses get mapped? If I execute a mapping as follows:
var source = new ModelPersonEntity { Id = 100, BeautyCompetitionsWon = 9 };
var target = Mapper.Map<PersonDto>(source);
target.BeautyCompetitionsWon
的期望值为9,但实际值为0.
The expected value for target.BeautyCompetitionsWon
is 9, but the actual value is 0.
推荐答案
问题1:我不知道.
问题2:使用.ConstructUsing()时,请确保返回的是所要映射的对象,而不是一个新的实例.
Question 2: When using the .ConstructUsing() make sure you return the mapped object you are after rather than a fresh instance.
例如
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>();
});
这篇关于使用AutoMapper从接口映射到具体类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!