2011-04-28 64 views
9

考慮以下源類型: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>(); 

我可以做如下(簡單的例子) - 鑑於我直到運行時才真正知道視圖模型的類型?

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

無論如何我現在正在嘗試這個了!

+0

對我剛剛試過這個,它看起來不可能 - 除非我錯過了什麼? – 2011-04-28 13:54:15

回答

18

我發現,如果我改變映射

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

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

然後它能正常工作,而無需使用的類型轉換器。

+0

哦,我的確如此。 – Rangoric 2011-04-28 14:48:13

1

您可以使用接口嗎?此外,在這種情況下,可能會有更好的非通用Mapper.Map implimentation。如果你設置了映射,你可以傳入類型。

+0

我不確定接口是否有用,非泛型還是需要我知道具體類型。 – 2011-04-28 14:10:54

+0

你不能傳入typeof(obj)作爲參數嗎?當然,你可以以某種方式解決這個問題。 – 2011-04-28 14:13:31

+0

我會和typeof致謝。 – 2011-04-28 14:21:52

0

沒有,如果你創建派生類型的映射,你應該當 地圖對象指定派生類也

3

你不能直接這樣做,但是你可以解決它的TypeConverter,這是不正確的。

在映射您將添加:

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實際上是你想要的類型。

它不會將基類型映射到彼此。如果那件事情我可以扭曲一點。

+0

看起來很有希望。基本類型無關緊要 - 它們在我的實際代碼中是抽象的。 – 2011-04-28 14:17:53