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

12

我已经创建了一个 dotNetFiddle,展示了这里的问题


这是我尝试做的事情的一个简化示例……假设我有以下接口:

public interface IPerson
{   
    int Id { get; set; }     
}

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

在实际的实现中,有许多不同类型的人(例如IUglyPerson等)。这些是实体类型的契约,例如如下:

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

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

注意: 每种合同类型可能会有多个实现 - 例如,IModelPerson 也可以由 SupermodelEntity 实现。

我们希望将实体类型映射到数据传输对象(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"; }
    }
}

因此,我们创建了一个映射:

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

所以,我这里有两个问题。

1. 是否有任何方法可以在没有使用ConstructUsing子句的情况下创建映射?我认为具有更具体版本的CreateMap应该已经为我们处理了这个问题,但如果我没有ConstructUsing子句,AutoMapper会告诉我“不能创建抽象类的实例”。

2. 为什么我的子类属性没有被映射?如果我执行以下映射:

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

target.BeautyCompetitionsWon 的期望值为9,但实际值为0。

1个回答

12

问题1: 据我所知没有。

问题2: 当使用.ConstructUsing()时,请确保返回您想要的映射对象,而不是一个新的实例。

例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接