2010-10-05 38 views
5

在我正在開發的項目中,我們將自動生成的DTO映射到業務對象。數據庫有一個不尋常的(但基本一致的)命名約定,這意味着可以將大多數DTO屬性名稱轉換爲其等價的業務對象屬性名稱,從而節省了許多代碼行。如何讓AutoMapper處理自定義命名約定?

例如,在DTO(和數據庫)中,我們有一個名爲account_ID__created的屬性,該屬性將映射到名爲CreatedAccountId的BO屬性。這是MemberNameTransformer.GetBoMemberName()中發生的一種轉換,所以它不像使用不同分隔符的稍微不同的約定那麼簡單。

繼我在AutoMapper源代碼有可用的,我這是我最好的猜測:

public class DtoBoMappingOptions : IMappingOptions 
{ 
    public INamingConvention SourceMemberNamingConvention 
    { 
     get { return new PascalCaseNamingConvention(); } 
     set { throw new NotImplementedException(); } 
    } 

    public INamingConvention DestinationMemberNamingConvention 
    { 
     get { return new PascalCaseNamingConvention(); } 
     set { throw new NotImplementedException(); } 
    } 

    public Func<string, string> SourceMemberNameTransformer 
    { 
     get { return s => s; } 
     set { throw new NotImplementedException(); } 
    } 

    public Func<string, string> DestinationMemberNameTransformer 
    { 
     get { return MemberNameTransformer.GetBoMemberName; } 
     set { throw new NotImplementedException(); } 
    } 
} 

現在,我該如何告訴映射器使用這些選項映射到SomeDto時SomeBusinessClass?我意識到我可能在IMappingOptions中有錯誤的接口。我試圖完成的真正的肉在MemeberNameTransformer.GetBoMemberName()

附加題:我如何告訴映射器使用這些選項映射任何 IDto到IBusinessObject什麼時候?

回答

6

如果事情真的一致,像textFirstName,你可以使用一些內置函數。

Mapper.Initialize(cfg => cfg.RecognizePrefixes(new[] { "text" })); 

否則,你需要編寫自己的INamingConvention類,看起來是這樣的..

class DTONaming : INamingConvention 
{ 

    #region INamingConvention Members 

    public string SeparatorCharacter 
    { 
     get { return string.Empty; } 
    } 

    public Regex SplittingExpression 
    { 
     get { return new Regex(""); } 
    } 

    #endregion 
} 

然後你就可以用automapper寄存器。

Mapper.Initialize(cfg => cfg.SourceMemberNamingConvention = new DTONaming()); 

而且AutoMapper將使用此的任何映射,所以如果你需要限制這些前綴或自定義命名對象可能需要初始化並重新初始化它或東西的登記。我懷疑這個命名方案會帶來什麼後果。

編輯

與您最近加入您將使用SourceMemberNameTransformer代替。這使您可以編寫一個可以自己轉換名稱的函數。

Mapper.Initialize(cfg => cfg.SourceMemberNameTransformer = ConvertNames); 
private static string ConvertNames(string inputString) 
{ 
    var sections = inputString.Split('_'); 
    // transform the sections into w/e you need 
    return inputString; 
} 
+0

我不認爲這將適用於我所需要的。我已經更新了這個問題,以反映我正在使用的命名約定。我真的需要我的Func 來說明目標成員來自哪個源成員。 – 2010-10-05 21:57:06

+0

@Josh Kodroff檢查更新的答案,我認爲這將是你需要的。 – Jab 2010-10-06 13:30:56

+0

就是這樣!我只是想不出在哪裏設置SourceMemberNameTransformer。現在,我在多層(DTO,BO,VM)中使用Mapper,所以我不想普遍使用該變壓器。任何想法如何確保不會發生? – 2010-10-06 13:53:40