Automapper自动解析要映射到的正确子类?

时间:2011-04-28 13:47:58

标签: c# polymorphism automapper

考虑以下源类型:

public class BaseViewModel
{
   public string Prop1 { get; set; }
}

public class FirstViewModelImpl : BaseViewModel
{
   public string Prop2 { get; set; } 
}

public class SecondViewModelImpl : BaseViewModel
{
   public string AnotherProp { get; set; }
}

以下目的地类型

public class BaseDto
{
   public string Prop1 { get; set; }
}

public class FirstDtoImpl : BaseDto
{
   public string Prop2 { get; set; } 
}

public class SecondDtoImpl : BaseViewModel
{
   public string AnotherProp { get; set; }
}

使用以下映射:

Mapper.CreateMap<FirstViewModelImpl,FirstDtoImpl>();
Mapper.CreateMap<SecondViewModelImpl,SecondDtoImpl>();

我可以执行以下操作(简单示例) - 假设我在运行时之前实际上并不知道viewmodel的类型吗?

BaseViewModel myViewModel = GetAViewModelFromSomewhere();
FirstDtoImpl dto = (FirstDtoImpl)Mapper.Map<BaseViewModel,BaseDto>(myViewModel);

我现在正在尝试这个!

4 个答案:

答案 0 :(得分:18)

我发现如果我将映射更改为

Mapper.CreateMap<BaseViewModel,BaseDto>()
        .Include<FirstViewModelImpl,FirstDtoImpl>()
        .Include<SecondViewModelImpl,SecondDtoImpl>();

Mapper.CreateMap<FirstViewModelImpl,FirstDtoImpl>();
Mapper.CreateMap<SecondViewModelImpl,SecondDtoImpl>();

然后它不按预期工作,不使用类型转换器。

答案 1 :(得分:3)

你不能直接这样做,但你可以使用TypeConverter解决它。

在Mappings中,您将添加:

Mapper.CreateMap<BaseViewModel, BaseDto>()
    .ConvertUsing<MyTypeConverter>();

然后您可以像这样创建转换器:

public class MyTypeConverter : TypeConverter<BaseViewModel, BaseDto>
{
    protected override BaseDto ConvertCore(BaseViewModel tViewModel)
    {
        BaseDto vResult = null;
        if(tViewModel is FirstViewModelImpl)
        {
            var vSource = tViewModel as FirstViewModelImpl;
            vResult = Mapper.Map<FirstViewModelImpl,FirstDtoImpl>(vSource);
        }
        else if(tViewModel is SecondViewModelImpl )
        {
            var vSource = tViewModel as SecondViewModelImpl ;
            vResult = Mapper.Map<SecondViewModelImpl ,SecondDtoImpl>(vSource);
        }
        return vResult;
    }
}

然后你就可以使用它:

BaseDto dto= Mapper.Map<BaseViewModel,BaseDto>(myViewModel);

并且dto实际上属于你想要的类型。

虽然它不会将Base类型映射到彼此。如果重要的话我可以再扭曲一下。

答案 2 :(得分:1)

您可以使用界面吗?此外,还有一个非通用的Mapper.Map实现,在这种情况下可能会更好。如果您设置了映射,则只需传入类型即可。

答案 3 :(得分:0)

如果您为何时创建派生类型的映射,则这不正确 map对象也指定派生类