redwarrior’s diary

C#, ASP.NET, WEB, G*などの雑多な情報

AutoMapper は使わない!

ASP.NET MVC で開発をしている時に気になってくるのが、Entity Framework で作成したエンティティと画面で使用するモデル(ViewModel)の詰め替えをどうするかということ。

少しググってみると、AutoMapper を使用すると良いと出てくる。プロパティを一つずつコピーするのはいかにも冗長な作業でなんとかしたいと思うのはわかるし、一行でプロパティのコピーが出来るのは便利だと思う。ただし、これはやりたくない。

.NET ではなく Java の話だけど、DXO(Data Exchange Object)というものが話題になったことがあった。その時に DBFlute というフレームワークを作っている id:jflute さんの書いていたことが印象に残っている。
DXO を提供するツールを使うことで開発は少し削減されるかもしれないが、エラー発生時にデバッグで悩んでしまえばトータルではマイナスになるという趣旨の内容だったと思う。
その後調べた範囲では DXO を使ったツールはそれほど流行らなかったようで、この主張は的を得ていると思った。

AutoMapper はその時の DXO .NET で実現するものだと思えるので、使わない方が良いと思っている。
しかし、冗長なコードを書くのもまた面倒なのでどうしたものかなと思い、でも、C# には LINQ があるからそんなに冗長にはならないのではないかとも思った。
今回、実際に試してみた結果、想像以上にスッキリと書けて、マジで AutoMapper は使わなくても良いと思えたので、ここに方法を記す。

前置きがものすごい長くなったが、ソースコードで表すとこんな感じ。

モデルクラス(Book.cs)

public class Book
{
    public string Title { get; set; }
    public Author author { get; set; }
}

モデルクラス(Author.cs)

public class Author
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

ViewModel(BookViewModel.cs)

public class BookViewModel
{
    public string Title { get; set; }
    public string AuthorName { get; set; }
}

詰め替え処理

//単独オブジェクト
BookViewModel vmodel = BuildViewModel(book);

//コレクション
IEnumerable<BookViewModel> vmodels = books.Select(BuildViewModel); //booksはIEnumerable<Book>

//詰め替えを行うメソッド
private static BookViewModel BuildViewModel(Book book)
{
    return new BookViewModel
    {
        Title = book.Title,
        AuthorName = book.FirstName + " " + book.LastName,
    };
}

staticの詰め替え用のメソッドを用意する必要はあるが、呼び出す側は単独オブジェクトだろうが、コレクションだろうが1行で済む。

プロパティ名の異なるクラス間の変更や、コレクションの変更では、AutoMapperでも対応付けるための記述が必要になるので、AutoMapperを使って手間を省けるのはプロパティが同じクラス間だけなのではと思う。

プロジェクト都合にも寄るのかもしれないけど、デバッグ時のわかりやすさと天秤にかけると、自分はAutoMapperはいらないかなと思った。