2012-06-21 20 views
25

今天我升級使用AutoMapper 1.1版到現在使用AutoMapper 2.1一個全功能的應用程序,我對面,我用以前的版本從未遇到過的一些問題來了。AutoMapper使用了錯誤的構造

這裏是我的代碼映射的例子來自DTO對象

public class TypeOne 
{ 
    public TypeOne() 
    { 
    } 

    public TypeOne(TypeTwo two) 
    { 
     //throw ex if two is null 
    } 

    public TypeOne(TypeTwo two, TypeThree three) 
    { 
     //throw ex if two or three are null 
    } 

    public TypeTwo Two {get; private set;} 

    public TypeThree Three {get; private set;} 
} 

public class TypeOneDto 
{ 
    public TypeOneDto() 
    { 
    } 

    public TypeTwoDto Two {get; set;} 

    public TypeThreeDto Three {get; set;} 
} 

...

Mapper.CreateMap<TypeThreeDto, TypeThree>(); 
Mapper.CreateMap<TypeTwoDto, TypeTwo>(); 
Mapper.CreateMap<TypeOneDto, TypeOne>(); 

var typeOne = Mapper.Map<TypeOne>(typeOneDto); 

但是我V2.1遇到的第一個問題是當其中一個參數爲null且應該使用1參數構造函數時,AutoMapper試圖使用具有2個參數的構造函數。

然後我試圖用

Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(x => new TypeOne()); 

但我一直得到我解決不了的「曖昧調用」的錯誤。

我又試圖

Mapper.CreateMap<TypeOneDto, TypeOne>().ConvertUsing(x => new TypeOne()); 

,但這併成功地創建使用參數的構造函數的TypeOne對象,但隨後沒有設置專用setter屬性。

我已經看過了AutoMapper網站上的幫助和下載的源代碼有一個良好的外觀,但沒有提供有關文檔很少得到遠沒有許多單元測試ConstructUsing。

有什麼明顯我很想念我應該用V2.1改變?我感到驚訝的是,它從v1.1中發生了很大的變化。

+0

可能重複(http://stackoverflow.com/questions/2239143/automapper-how-to-map-to-constructor-parameters-而不是屬性設置者) –

+0

當我使用「ConstructUsing」時,我總是收到上面提到的同樣的錯誤。當我使用無參數構造函數創建一個新對象時,使用「Ambiguous Invocation」。 –

回答

48

你只需要添加explicit cast

Func<ResolutionContext, TypeOne> 

下面是代碼:

  1. 排序目標類型的構造函數:

    Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(
          (Func<ResolutionContext, TypeOne>) (r => new TypeOne())); 
    

    當前AutoMapper的版本如下所述工作按參數計數

    destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length); 
    
  2. 採用第一個構造函數,哪些參數匹配源屬性(不檢查空值)。在你的情況下,它是兩個參數的構造函數。

[Automapper - 如何映射到構造函數的參數,而不是屬性setter]的
+0

這只是救了我一些悲傷。完美地使用最新版本的AutoMapper(3.2.1.0):)謝謝! – Stu1986C

+3

雖然這是一個相當老的帖子,但我很高興我發現它:AutoMapper認爲與構造函數匹配的順序似乎在版本4中再次發生了變化。0.4。爲避免出現問題,在保守的一面可能總是指定如果您有多個構造函數,AutoMapper應該使用哪個構造函數。另外,作爲第二個建議,應該有一個自動化測試來設置所有的地圖,然後調用Mapper.AssertConfigurationIsValid()。這樣你可以儘早地解決問題。快樂的編碼! – Manfred