AutoMapperを動かしてみる
2011年9月3日 コメントを残す
0.前置き
仕事でAutoMapperを触る機会がありました。
覚書のために、その記録を残しておきます。
1.AutoMapperとは
規約ベースで利用するオブジェクト-オブジェクトマッパーです。
(A convention-based object-object mapper. )
英語の訳をそのまま。。。
DTOからEntityやViewModelにデータを詰め直す時に使います。
詰め替えるコードをえんえんと書かなくてもOKというわけです。例えば以下のようなコードがあるとします。
// 変換元を SrcEmployee srcEmployee = ...; // 変換先に、詰め直す! var destEmp = new DestEmployee { Name = srcEmp.Name, Age = Convert.ToInt32(srcEmp.Age), Status = EmployeeStatusResolver(srcEmp.Status), HireDate = CustomDateTimeConverter(srcEmp.Status) };
規約に従えって、AutoMapperを利用すればこんな感じになります。(もろもろ省いています)
Mapper.CreateMap<SrcEmployee, DestEmployee>(); var destEmp = Mapper.Map<SrcEmployee, DestEmployee>(srcEmp);
2.インストール
AutoMapperのインストールはnugetでできます。とても簡単。
3.実際に使ってみる
課題を作って、実際に変換処理を書いて見ます。
3-1.(課題)変換元と変換先のクラス
SrcEmployeeからDestEmployeeにデータの詰め替えを行います。
(プロパティ名の対応関係の規約は、説明が煩雑になりそうなので省きます。)
/// <summary> /// 変換元のクラス /// </summary> public class SrcEmployee { public string Name { get; set; } public string Age { get; set; } public string Status { get; set; } public DateTime HireDate { get; set; } } /// <summary> /// 変換先のクラス /// </summary> public class DestEmployee { public string Name { get; set; } public int Age { get; set; } public EmployeeStatus Status { get; set; } public string HireDate { get; set; } }
この課題に対して、型変換や、値の変換等、変換ルールが必要なところをマッピング定義に書いていきます。
3-2.グローバルな変換規則を作る
どのマッピングでも使うような変換規則を作ります。
今回は主に2つ。
- stringをintに変換:Convet.ToInt32()を利用
- DateTimeをstringに変換:独自のコンバーターを利用
作った独自のコンバーターはこんな感じ。
public class CustomDateTimeConverter : TypeConverter<DateTime, string> { protected override string ConvertCore(DateTime source) { return source.ToString("yyyy年MM月dd日"); } }
3-3.変換元のクラスと変換先のクラスに依存する変換規則を作る
今回の例ですと、Statusというプロパティになります。
stringから、enumのEmployeeStatusに変換しています。今度は独自のリゾルバーを作ります。
public class EmployeeStatusResolver : ValueResolver<SrcEmployee, EmployeeStatus> { protected override EmployeeStatus ResolveCore(SrcEmployee source) { switch (source.Status) { case "在職": return EmployeeStatus.Stay; case "退職": return EmployeeStatus.Exit; case "長期休暇中": return EmployeeStatus.LongHoliday; default: throw new UnKnowonEmployeeStatusException(); } } }
3-4.変換定義をする
今まで考えた変換定義をコードにおこします。
// 2-2用のルール Mapper.CreateMap<string, int>().ConvertUsing(Convert.ToInt32); Mapper.CreateMap<DateTime, string>().ConvertUsing<CustomDateTimeConverter>(); // SrcEmployeeからDestEmployeeの変換定義と、2-3用のルール Mapper.CreateMap<SrcEmployee, DestEmployee>() .ForMember(dest => dest.Status, opt => opt.ResolveUsing<EmployeeStatusResolver>());
3-5.マッピング
最後にマッピング!!これだけで、データの詰め直しが完了します。
var destEmp = Mapper.Map<SrcEmployee, DestEmployee>(srcEmp);
4.サンプルを書いてみての補足
最初にマッピングルールをいろいろ作らなきゃいけないのは面倒です。
ただかなりの確率で使いまわせることができるので、一回作ってしまえば良いです。
ASP.NET MVCで使うと便利だよ~って、マイコミジャーナルの記事でも言ってますので
興味のある方は、参考資料のほうをチェックしてみてください。
5.サンプルコード
サンプルコードはgithubにホスティングしてあります。
AutoMapperのサンプル
コード本体
※実は、初github!
6.参考資料
本家のページは以下です。CodePlexや、Google Groupsや、githubに情報が散らばってますけど、とりあえずここから行けばよし。
AutoMapperの本家のページ
マイコミジャーナルにも記事があったので載せておきます。
AutoMapperでオブジェクト間のデータコピーを行う