AutoMapperでUpperCamelCaseとPascalCaseをMapする
今年、初ブログだったりします。(気力がね・・・)
さてタイトルの通りAutoMapperでUpperCamelCaseとPascalCaseをMapしたい。
C#でUpperCamelCaseを使うことはほぼ無いのですが
DBがOracleだったりしてORMもシンプルなものだったりすると
UpperCamelCaseで定義したクラスに一旦受けざる負えない時もあります。
それを簡単にPascalCaseで定義したクラスに移したいって時の話です。
(まああまり需要は無いですかねー)
以前に@xin9leさんが、このような記事を書かれています。
AutoMapperで特定の命名規則で変換する - xin9le.net
基本的にはこれでできたのですが、これにプラスして
PascalCaseからUpperCamelCaseへのMapもしたいのです。
これがかなり嵌りました。
とりあえずググると
Automapper: How to leverage a custom INamingConvention? - Stack Overflow
こんな感じで出てきますが、CreateProfileしてWithProfileするやり方だとどうもうまく行きませんでした。
で、ようやくできたのがこのやり方
とりあえず適当に受け渡しするクラスを作ります。
class Employee { public int EmployeeId { get; set; } public string EmployeeName { get; set; } } class EmployeeDataModel { public int EMPLOYEE_ID { get; set; } public string EMPLOYEE_NAME { get; set; } }
INamingConventionを実装するクラスを作ります。
public class UpperSnakeCaseNamingConvention : INamingConvention { public string SeparatorCharacter { get { return "_"; } } public Regex SplittingExpression { get { return new Regex(@"[\p{Lu}0-9]+(?=_?)"); } } }
Profileクラスを継承するクラスをUpperCamelCaseからPascalCaseに変換するクラスと
逆にPascalCaseからUpperCamelCaseに変換するクラスを作ります。
class UpperSnakeToPascalProfile : Profile { public override string ProfileName { get { return "UpperScakeToPascal"; } } protected override void Configure() { // こちらはSourceに対して上で作ったINamingConventionを実装したクラスを設定 this.SourceMemberNamingConvention = new UpperSnakeCaseNamingConvention(); // 上の設定でMapしたいクラスは、ここでCreateMapすること this.CreateMap<EmployeeDataModel, Employee>(); } } class PascalToUpperSnakeProfile : Profile { public override string ProfileName { get { return "PascalToUpperSnake"; } } protected override void Configure() { // こちらはDestinationに対して上で作ったINamingConventionを実装したクラスを設定 this.DestinationMemberNamingConvention = new UpperSnakeCaseNamingConvention(); this.CreateMap<Employee, EmployeeDataModel>(); } }
で、これを呼び出してうまく行くかテストします。
[TestClass] public class UnitTest1 { public UnitTest1() { // Mappingの設定をする Mapper.Initialize(config => { // AddProfileで上で作成したProfileクラスを設定 config.AddProfile<UpperSnakeToPascalProfile>(); config.AddProfile<PascalToUpperSnakeProfile>(); }); Mapper.AssertConfigurationIsValid(); } [TestMethod] public void TestMethod1() { var dm = new EmployeeDataModel { EMPLOYEE_ID = 1, EMPLOYEE_NAME = "山田太郎" }; var dto = Mapper.Map<Employee>(dm); Assert.AreEqual(dm.EMPLOYEE_ID, dto.EmployeeId); Assert.AreEqual(dm.EMPLOYEE_NAME, dto.EmployeeName); } [TestMethod] public void TestMethod2() { var dto = new Employee { EmployeeId = 2, EmployeeName = "佐藤一郎" }; var dm = Mapper.Map<EmployeeDataModel>(dto); Assert.AreEqual(dto.EmployeeId, dm.EMPLOYEE_ID); Assert.AreEqual(dto.EmployeeName, dm.EMPLOYEE_NAME); } }
という感じでちゃんとMapすることができました。