2014-06-07 46 views
4

我有一個Person和PersonViewModel。我從Person => PersonViewModel創建了一個映射。問題是,PersonViewModel的唯一構造函數需要一個參數(它有一個依賴項,我想注入),AutoMapper抱怨,因爲它說它需要一個無參數的構造函數。AutoMapper構造服務忽略使用

要解決它,我用了ConstructServicesUsing方法,但我一直沒成功與它:(

爲了說明的情況下,我創建了一個測試給你看我在做什麼。這是非常簡單:

[TestMethod] 
    public void TestConstructServicesUsing() 
    { 
     Mapper.Initialize(configuration => 
     { 
      configuration.ConstructServicesUsing(FactoryMethod); 
      configuration.CreateMap<Person, PersonViewModel>(); 
     }); 

     Mapper.AssertConfigurationIsValid(); 

     var person = new Person(); 
     var personViewModel = Mapper.Map<Person, PersonViewModel>(person); 
    } 

    private object FactoryMethod(Type type) 
    { 
     throw new NotImplementedException(); 
    } 
} 

代碼的其餘部分的類和接口定義它們幾乎空

public class SomeyDependency : ISomeDependency 
{ 
} 

public class PersonViewModel 
{ 
    private readonly ISomeDependency service; 

    public PersonViewModel(ISomeDependency service) 
    { 
     this.service = service; 
    } 

    public string Name { get; set; } 
} 

public class Person 
{ 
    public string Name { get; set; } 
} 

public interface ISomeDependency 
{ 
} 

正如你看到的,我提供AutoMapper一個FactoryMeth。 od,但它永遠不會被調用。

當它到達測試的最後一行(Mapper.Map < ...>()),它拋出一個excepton說:

AutoMapper.AutoMapperMappingException: 

Mapping types: 
Person -> PersonViewModel 
MappingWithContainerTests.Person -> MappingWithContainerTests.PersonViewModel 

Destination path: 
PersonViewModel 

Source value: 
MappingWithContainerTests.Person ---> System.ArgumentException: Type needs to have a constructor with 0 args or only optional args 
Parameter name: type 

什麼問題? 爲什麼不調用FactoryMethod?

+2

我知道這是一個年紀大一點的問題,但在CreateMap <>有一個_.ConstructUsingServiceLocator ()_應該完成這項工作,但在我的情況下它不起作用。 – khorvat

+0

@khorvat +1,在CreateMap <>表達式後面添加.ConstructUsingServiceLocator()使它適用於我,我的情況看起來與OP的示例非常相似。不知何故,我預計映射器將始終使用工廠方法(如果提供的話)。不過,我想知道爲什麼它不適合你。 –

回答

-1

由於@khorvat提到缺少的地方.ConstructUsingServiceLocator(),用於具體映射。

您也可以通過

.ConstructUsing(source => Method(source.anySourceOptions)) 

直接設置構造函數或爲例外說:

PersonViewModel,必須有0 ARGS或只可選 ARGS一個構造函數。你只有一個構造函數1個不是可選的參數

你可以不ARGS再創建一個構造函數:

public PersonViewModel() 
{ 
    this.service = new SomeDependency(); 
} 
+0

這不是解決問題的辦法。 – Dima

+0

是的。然後將一個類映射到另一個類,調用構造函數並創建新對象。所以mapper不知道他是如何用參數調用構造函數的。所以選項是:1)使用不帶參數的構造函數。 2)說mapper從sorce中取參數 - .ConstructUsing(source => new PersonViewModel(source.service)3)直接傳參數 - 與2相同,但是你可以從IoC容器獲得它,例如.ConstructUsing( source => new PersonViewModel(_kernel.Get ) – Vlad

+0

僅僅爲了映射的目的而添加另一個構造函數不是一個選項:a)新構造函數可能會影響現有設計; b)班級代碼可能無法更改。 – Dima