AutoMapperを動かしてみる

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でオブジェクト間のデータコピーを行う

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。