2017-07-10 44 views
1

我需要實現一個可插入系統,其中Automapper配置文件可以由許多DLL提供。Automapper - 可插入映射

被映射對象具有人的列表:

public class CompanySrc 
{ 
    public List<PersonSrc> Persons {get;set;} 
} 

public class CompanyDest 
{ 
    public List<PersonDest> Persons {get;set;} 
} 

PersonSrc和PersonDest是可以在每個DLL被擴展的抽象類:

DLL1:

public class EmployeeSrc : PersonSrc 
{ 
    ... 
} 


public class EmployeeDest : PersonDest 
{ 
    ... 
} 

DLL2 :

public class ManagerSrc : PersonSrc 
{ 
    ... 
} 


public class ManagerDest : PersonDest 
{ 
    ... 
} 

當時的想法是,以實現類似於此:

public class DLL1Profile : Profile 
{ 
    public DLL1Profile() 
    { 
     CreateMap<PersonSrc, PersonDest>() 
       .Include<EmployeeSrc, EmployeeDest>(); 
     CreateMap<EmployeeSrc, EmployeeDest>(); 
    } 
} 


public class DLL2Profile : Profile 
{ 
    public DLL2Profile() 
    { 
     CreateMap<PersonSrc, PersonDest>() 
       .Include<ManagerSrc, ManagerDest>(); 
     CreateMap<ManagerSrc, ManagerDest>(); 
    } 
} 

映射在下列方式

var mc = new MapperConfiguration(cfg => 
      { 
       cfg.CreateMap<CompanySrc, CompanyDest>() 
       cfg.AddProfile(new DLL1Profile()); 
       cfg.AddProfile(new DLL2Profile()); 
      }); 

      IMapper sut = mc.CreateMapper(); 
      var result = sut.Map<CompanyDest>(companySrc); 

完成,但這種方法是行不通的。當「人員」列表中包含員工和經理時,我試圖映射整個列表,我得到一個異常。 有什麼建議嗎?

+1

你,因爲多態性是什麼意思?所以你有一個單獨的列表,裏面有'People',有些列表可能是'Manager',有些可能是'Employee'? 如果是這種情況,應用你的'Profile'會導致一個異常,因爲當列表包含兩種類型時,它將嘗試映射到'Manager'或'Employee'... 說到這一點,我認爲Automapper不會映射在Dest上不存在的道具,而是拋出異常。也許這個問題是缺少一些信息(即什麼是異常消息?) –

+0

我編輯了更多信息的問題。拋出的異常是誤導,因爲它似乎映射器不能映射一個字段,但內部有一個對象引用沒有設置,因爲可能automapper試圖創建一個「Person」的實例,但因爲它是抽象的不能。 – Luca

+0

看: https://github.com/AutoMapper/AutoMapper/wiki/Mapping-inheritance 和 https://stackoverflow.com/questions/39884805/polymorphic-mapping-of-collections-with- automapper –

回答

0

您看到此問題,因爲您有多個CreateMap<PersonSrc, PersonDest>()的調用 - 只能存在一個映射。

當您在不同的DLL中擴展基類時,請不要使用.Include,而應使用.IncludeBase。包含要求包含您的基類的配置文件能夠引用派生類,這很可能不是您想要發生的事情。

你應該定義你的基礎測繪共同的地方,大概是哪裏人的定義:

CreateMap<PersonSrc, PersonDest>(); 

在您的個人資料DLL1等,使用IncludeBase代替:

CreateMap<ManagerSrc, ManagerDest>() 
    .IncludeBase<PersonSrc, PersonDest>(); 
+0

謝謝你的回答。在雙映射聲明之後,如果我嘗試使用cm檢查配置。AssertConfigurationIsValid();'我得到了一個由雙重配置引起的錯誤,但是錯誤信息的文本包含了使用'AllowAdditiveTypeMapCreation'的建議。如果我在雙重映射之前將屬性設置爲true,斷言不會觸發任何異常,但映射仍然不起作用。然而,我試圖以你的方式聲明映射,似乎工作正常。謝謝 – Luca