按约定自动映射器定义,无需显式创建映射



我正在尝试创建自动映射器约定,用于在带有下划线的大写属性的DTO和具有帕斯卡大小写的业务POCO之间进行映射。

我想这样做而不为每个类显式调用CreateMap,因为映射规则在任何地方都是相同的。

DTO以"T_"为前缀。

// DTO 
public class T_ACCOUNT
{
public int ID { get; set; }
public int? PROFILE_ID { get; set; }
public bool DELETED { get; set; }
public string EMAIL { get; set; }
public bool IS_EMAIL_CONFIRMED { get; set; }
public DateTime TIME { get; set; }
}
// business model
public class Account
{
public int Id { get; set; }
public int? ProfileId { get; set; }
public bool Deleted { get; set; }
public string Email { get; set; }
public bool IsEmailConfirmed { get; set; }
public DateTime Time { get; set; }
}

所以我像这样创建映射器。

var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new DtoToBusinessProfile());
});
IMapper mapper = new Mapper(config);

配置文件如下所示。

public class DtoToBusinessProfile : Profile
{
public DtoToBusinessProfile()
{
// this should match mapping between "Account" and "T_ACCOUNT"
AddConditionalObjectMapper()
.Where((s, d) =>
{
return s.Name == d.Name.Substring(2).Pascalize();
});
// Now what?
}
}

我在Automapper github中创建了一个功能请求,因为我无法使INamingConvention界面正常工作。

有人告诉我,我想要的东西也可以通过使用ForAllMaps,但我不知道如何处理它。

在自动映射器中发现了一个错误,但也发现了一个具有两个映射器的工作解决方案。显然,LowerUnderscoreNamingConvention也适用于大写属性。

IMapper dtoToBusinessMapper = new MapperConfiguration(cfg =>
{
cfg.AddConditionalObjectMapper()
.Where((s, d) => s.Name == d.Name.Substring(2).Pascalize());
cfg.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
cfg.DestinationMemberNamingConvention = new PascalCaseNamingConvention();
}).CreateMapper();
IMapper businessToDtoMapper = new MapperConfiguration(cfg =>
{
cfg.AddConditionalObjectMapper()
.Where((s, d) => s.Name == "T_" + d.Name.Underscore().ToUpperInvariant());
cfg.SourceMemberNamingConvention = new PascalCaseNamingConvention();
cfg.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention(); 
}).CreateMapper();
T_ACCOUNT tableRow = new T_ACCOUNT()
{
DELETED = 0,
EMAIL = "asdf@asdf.cz",
ID = 8,
IS_EMAIL_CONFIRMED = 1,
PROFILE_ID = 11,
TIME = DateTime.Now
};
Account businessModel = dtoToBusinessMapper.Map<Account>(tableRow);
T_ACCOUNT backToDto = businessToDtoMapper.Map<T_ACCOUNT>(businessModel);