【ASP.NET】面倒なオブジェクトマッピングはAutoMapperにやらせよう

ASP.NET
スポンサーリンク

AutoMapper とは?

オブジェクトの詰め替えをしてくれる .NET のライブラリです。
マッパーを使うことでオブジェクトの詰め替えをその都度記述する必要がなくなるのでコーディング量を減らすことが出来ます。
また、オブジェクト間のプロパティの対応関係を局所化することが出来るので、修正箇所が限定されます。


AutoMapper を使わない場合

MVC ではよく Entity を ViewModel に詰め替えることがあるかと思います。
例えば DB から取得したユーザを ViewModel に詰め替えて返す場合こんな感じになるかと思います。

public class UserController
{
    public ActionResult Detail(string name)
    {
        // DB から USER を取得したとする
        var user = Service.FindUserByName(name);
        // USER -> UserViewModel
        var viewModel = new UserViewModel()
        {
            UserId = user.USER_ID;
            UserName = user.USER_NAME;
            Tel = user.TEL;
            Mail = user.MAIL;
        }
        return View(viewModel);
    }
}
public class USER
{
    public string USER_ID { get; set; }
    public string USER_NAME { get; set; }
    public string TEL { get; set; }
    public string MAIL { get; set; }
}
public class UserViewModel
{
    public string UserId { get; set; }
    public string UserName { get; set; }
    public string Tel { get; set; }
    public string Mail { get; set; }
}

先ほどの Controller に一覧を返すメソッドを追加した場合はこんな感じになると思います。

public class UserController
{
    public ActionResult Detail(string name)
    {
        // DB から USER を取得したとする
        var user = Service.FindUserByName(name);
        // USER -> UserViewModel
        var viewModel = new UserViewModel()
        {
            UserId = user.USER_ID;
            UserName = user.USER_NAME;
            Tel = user.TEL;
            Mail = user.MAIL;
        }
        return View(viewModel);
    }

    public ActionResult List()
    {
        // DB から USER 一覧を取得したとする
        var users = Service.FindUsers();
        var viewModels = new List<UserViewModel>();
        foreach(var user in users)
        {
            // USER -> UserViewModel
            var viewModel = new UserViewModel()
            {
                UserId = user.USER_ID;
                UserName = user.USER_NAME;
                Tel = user.TEL;
                Mail = user.MAIL;
            };
            viewModels.Add(viewModel);
        }         
        return View(viewModels);
    }    
}

詰め替えまくってますね(笑)。
例えば「USER に FAX も追加しよう」となったとき、詰め替えている箇所全て修正する必要がありますね。

public class UserController
{
    public ActionResult Detail(string name)
    {
        // DB から USER を取得したとする
        var user = Service.FindUserByName(name);
        // USER -> UserViewModel
        var viewModel = new UserViewModel()
        {
            UserId = user.USER_ID;
            UserName = user.USER_NAME;
            Tel = user.TEL;
            // 追加
            Fax = user.FAX;
            Mail = user.MAIL;
        }
        return View(viewModel);
    }

    public ActionResult List()
    {
        // DB から USER 一覧を取得したとする
        var users = Service.FindUsers();
        var viewModels = new List<UserViewModel>();
        foreach(var user in users)
        {
            // USER -> UserViewModel
            var viewModel = new UserViewModel()
            {
                UserId = user.USER_ID;
                UserName = user.USER_NAME;
                Tel = user.TEL;
                // 追加
                Fax = user.FAX;
                Mail = user.MAIL;
            };
            viewModels.Add(viewModel);
        }         
        return View(viewModels);
    }    
}

いちいち該当箇所を探すのは面倒ですよね。
そこで AutoMapper です。

スポンサー

AutoMapper の使い方

AutoMapper の取得

NuGet から AutoMapper を取得してください。


AutoMapperConfig の作成

AutoMapperConfig.cs にマッピング情報を追加します。
App_Start 配下に用意してくださいね。

using AutoMapper;

public class AutoMapperConfig
{
    public static void RegisterAutoMappings()
    {
        Mapper.Initialize(cfg =>
        {
            // USER -> UserViewModel
            cfg.CreateMap<USER, UserViewModel>()
                .ForMember(d => d.UserId, o => o.MapFrom(s => s.USER_ID))
                .ForMember(d => d.UserName, o => o.MapFrom(s => s.USER_NAME))
                .ForMember(d => d.Tel, o => o.MapFrom(s => s.TEL))
                .ForMember(d => d.Mail, o => o.MapFrom(s => s.MAIL));
        });
    }
}

Global.asax への登録

AutoMapper を有効にします。

public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        AutoMapperConfig.RegisterAutoMappings();
    }
}
スポンサー

AutoMapper の利用

あとは Controller を修正します。

using AutoMapper;

public class UserController
{
    public ActionResult Detail(string name)
    {
        // DBからUSERを取得したとする
        var user = Service.FindUserByName(name);
        // USER -> UserViewModel
        var viewModel = Mapper.Map<UserViewModel>(user);
        return View(viewModel);
    }

    public ActionResult List()
    {
        // DBからUSER一覧を取得したとする
        var users = Service.FindUsers();
        var viewModels = new List<UserViewModel>();
        foreach(var user in users)
        {
            // USER -> UserViewModel
            var viewModel = Mapper.Map<UserViewModel>(user);
            viewModels.Add(viewModel);
        }         
        return View(viewModels);
    }    
}

とてもすっきりしましたね!
これで「USER に FAX も追加しよう」となったときは AutoMapperConfig を修正するだけで済みます。

using AutoMapper;

public class AutoMapperConfig
{
    public static void RegisterAutoMappings()
    {
        Mapper.Initialize(cfg =>
        {
            // USER -> UserViewModel
            cfg.CreateMap<USER, UserViewModel>()
                .ForMember(d => d.UserId, o => o.MapFrom(s => s.USER_ID))
                .ForMember(d => d.UserName, o => o.MapFrom(s => s.USER_NAME))
                .ForMember(d => d.Tel, o => o.MapFrom(s => s.TEL))
                .ForMember(d => d.Fax, o => o.MapFrom(s => s.FAX))
                .ForMember(d => d.Mail, o => o.MapFrom(s => s.MAIL));
        });
    }
}

最後に

AutoMapperConfig に Mapping 情報を書けば Mapper を呼び出すだけで簡単にマッピングされるようになります。
マッピング情報が AutoMapperConfig 一箇所にまとまるのでコードの見通しも良くなりメンテも捗るはずです。


関連情報

C# や ASP.NET に関連する記事を以下にまとめています。

テレワークしている方には以下の記事がおすすめです。
私のお気に入りは REALFORCE と R&F BELX のルイボスティーです。

エンジニア初心者向けに本当に使えるツールを紹介しています。
特に Notion はタスク管理に本当に便利です。

タイトルとURLをコピーしました