如何让AutoMapper处理自定义命名约定?

在我正在开发的项目中,我们将自动生成的DTO映射到业务对象。 数据库具有不同寻常的(但大致一致的)命名约定,这意味着可以将大多数DTO属性名称转换为其等效的业务对象属性名称,从而节省了许多代码行。

例如,在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 SourceMemberNameTransformer { get { return s => s; } set { throw new NotImplementedException(); } } public Func DestinationMemberNameTransformer { get { return MemberNameTransformer.GetBoMemberName; } set { throw new NotImplementedException(); } } } 

现在,在将SomeDto映射到SomeBusinessClass时,如何告诉Mapper使用这些选项? 我意识到我可能在IMappingOptions中有错误的界面。 我想要完成的真正的东西是在MemeberNameTransformer.GetBoMemberName()

额外功劳:在将任何 ID映射到IBusinessObject时,如何告诉Mapper使用这些选项?

如果事情真的一致,比如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; }