简体   繁体   English

使用 AutoMapper 从接口映射到具体类型

[英]Use AutoMapper to map from an interface to a concrete type

I've created a dotNetFiddle that demonstrates the question here .我创建了一个 dotNetFiddle 来演示这里的问题


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; }
}

In the real implementation, there are lots of different types of people (eg IUglyPerson , etc).在实际实现中,有很多不同类型的人(例如IUglyPerson等)。 These are the contracts for entity types, eg as follows:这些是实体类型的合同,例如如下:

public class PersonEntity : IPerson
{
    public int Id { get; set; }
}

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

Note : We may also have multiple implementations of each contract type - eg IModelPerson may also be implemented by SupermodelEntity .注意:我们也可能对每个合同类型有多个实现——例如IModelPerson也可能由SupermodelEntity实现。

We want to map our entity types to DTOs, which look something like this:我们想将我们的实体类型映射到 DTO,它看起来像这样:

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. Is there any way of creating the mappings without the ConstructUsing clause? 1. 有没有办法在没有ConstructUsing子句的情况下创建映射? 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".我认为拥有更具体的CreateMap版本会为我们解决这个问题,但是如果我没有ConstructUsing子句,AutoMapper 会告诉我“无法创建抽象类的实例”。

2. Why don't the properties from my subclasses get mapped? 2. 为什么我的子类的属性没有被映射? If I execute a 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. target.BeautyCompetitionsWon的预期值为 9,但实际值为 0。

Question 1: Not that I am aware of.问题 1:我不知道。

Question 2: When using the .ConstructUsing() make sure you return the mapped object you are after rather than a fresh instance.问题 2:使用.ConstructUsing()确保您返回的是您所追求的映射对象,而不是一个新实例。

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>();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM