如何在具有继承类型的映射中利用ConstructUsing?

时间:2015-05-08 16:24:10

标签: c# inheritance automapper

我需要映射以下类层次结构,但由于某种原因,我的ConstructUsing实现未被调用。我需要拦截层次结构中间的抽象类的构造,并根据原始模型的属性创建适当的实例。

实体类型:

public abstract class Profile {}

public sealed class ComposedProfile : Profile 
{
    public int Platform {get; set;}
}

的DTO:

public abstract class ProfileDto {}

public abstract class ComposedProfileDto : ProfileDto { }

public sealed class WindowsProfileDto : ComposedProfileDto { }

public sealed class AndroidProfileDto : ComposedProfileDto { }

我目前坚持使用的映射:

Mapper.CreateMap<Profile, ProfileDto>()
    .Include<ComposedProfile, ComposedProfileDto>();

Mapper.CreateMap<ComposedProfile, WindowsComposedProfileDto>()...{some complicated mapping};
Mapper.CreateMap<ComposedProfile, AndroidComposedProfileDto>()...{another complicated mapping}
Mapper.CreateMap<ComposedProfile, ComposedProfileDto>()
    .ConstructUsing(
        source =>
        {
            switch (source.Platform)
            {
                case 0:
                    return Mapper.Map<AndroidComposedProfileDto>(source);

                case 1:
                    return Mapper.Map<WindowsComposedProfileDto>(source);

                default:
                    throw new InvalidOperationException();
            }
        });

然后我有这样的映射代码,例如:

Profile profile = new ComposedProfile();
var mapped = Mapper.Map<ProfileDto>(profile);

使用当前实现,永远不会调用ConstructUsing块,映射器总是尝试将ComposedProfile的实例映射到WindowsComposedProfile。这似乎与CreateMap调用的顺序有关:如果我切换两个特定的映射调用并将CreateMap<ComposedProfile, AndroidComposedProfileDto>()置于CreateMap<ComposedProfile, WindowsComposedProfileDto>()之上,则它开始映射到{{1一直都是。

如果我同时删除了两个AndroidComposedProfileDto个调用,那么它会点击我的自定义CreateMap块,但当然会失败,因为我在方法中使用ConstructUsing并且映射本身没有宣布。

我需要在这里拥有这两个功能。我想配置映射,并且我还希望调用自定义构造代码。我怎样才能做到这一点?正如你所注意到的那样,我尝试了许多无用的东西。我还尝试在原始映射中包含Map调用的特定映射,重新排序Include调用,但没有任何作用。

我有许多其他类派生自CreateMapProfile,但是由于我需要自定义创建逻辑(所有其他映射都是一个),因此映射到组合dto是唯一一个给我带来问题的类。一个标准映射)。请记住,我的代码依赖于映射到基本dto类,因此我无法映射到更具体的类型。这个问题的解决方案需要使用映射到更基本的类。

0 个答案:

没有答案