#2年目エンジニアのメモ ~AutoMapperで値の転送を行うには~
##1. はじめに
先日、業務でAutoMapper
について学習しました。
自分の理解を深めるためにメモを兼ねて記事を作成します。
この記事ではFruit.cs
とApple.cs
という2つのクラスを作成し、前者から後者へ値を転送するやり方について説明していきます。
ここで扱う転送処理は次の通りです。
- 単純転送
- 固定値転送
- 編集を伴う転送
動作環境
この記事の内容は以下の環境で検証しました。
- VisualStudio2019
- AutoMapper v.7.0.1
##2. 作り方
FruitクラスからAppleクラスに値を転送する例を書いてみました。
以下のような仕様であると仮定します。
-
Fruit
というクラスを作成し、プロパティにID、産地、賞味期限、ブランドコードの4項目を定義します。 -
Apple
というクラスを作成し、ID、産地、賞味期限、ブランドコード、ブランド名、価格の6項目を定義します。 -
Fruit
からApple
の転送仕様は次の通りとします。
Fruit.cs | Apple.cs | 転送方法 |
---|---|---|
ID | ID | 同じ項目名の単純転送 |
Origin | ProductionArea | 違う項目名の単純転送 |
ExpirationDate | ExpirationDate | 3日前を計算して転送 |
BrandCode | BrandCode | 同じ項目名の単純転送 |
- | BrandName | BrandCodeを元に編集 |
- | Price | 固定値転送 |
先にソースコードをすべて示します。
using System;
public class Fruit
{
public int ID { get; set; }
public string Origin { get; set; }
public DateTime ExpirationDate { get; set; }
public int BrandCode { get; set; }
}
using System;
public class Apple
{
public int ID { get; set; }
public string ProductionArea { get; set; }
public DateTime ExpirationDate { get; set; }
public int BrandCode { get; set; }
public string BrandName { get; set; }
public decimal Price { get; set; }
}
using AutoMapper;
public class AppleMappingProfile : Profile
{
public AppleMappingProfile() : base()
{
CreateMap<Fruit, Apple>()
.ForMember(apple => apple.ProductionArea, option => option.MapFrom(fruit => fruit.Origin))
.ForMember(apple => apple.ExpirationDate, option => option.MapFrom(fruit => (fruit.ExpirationDate).Add(-3)))
.ForMember(apple => apple.BrandName, option => option.ResolveUsing<AppleBrandNameResolver>())
.ForMember(apple => apple.Price, option => option.UseValue(120))
}
}
using System;
public class AppleBrandNameResolver
{
public AppleBrandNameResolver : IValueResolver<Fruit, Apple, string>
{
public string Resolve(Fruit fruit, Apple apple, string destMember, ResolutionContext context)
{
if (fruit.BrandCode.Value == 111) return "ふじ";
if (fruit.BrandCode.Value == 222) return "ジョナゴールド";
return "その他の品種";
}
}
}
転送仕様を定義するAppleMappingProfile.cs
というクラスを作成します。
CreateMap<Fruit, Apple>()
でFruit
クラスからApple
クラスへの転送であることを宣言します。
CreateMap<>()
の<>の中に編集元項目と編集先項目を入れてマッピングを行います。
(1) 同じ項目名の単純転送
同じ項目名の場合は.ForMember
を書く必要がなく、CreateMap<>()
のみで転送が行われます。
Apple.cs
のID
とBrandCode
がこちらに当てはまります。
今回はそれぞれFruit.cs
のID
とBrandCode
を転送しています。
(2) 違う項目名の単純転送 : MapFrom
.ForMember
メソッドの引数に編集先項目(apple)を取り、MapFrom
メソッドの引数に編集元項目(fruit)を取ります。
Apple.cs
のProductionArea
がこちらに当てはまります。
今回はFruit.cs
のOrigin
を転送しています。
(3) 3日前を計算して転送 : MapFrom
.ForMember
メソッドの引数に編集先項目(apple)を取り、MapFrom
メソッドの引数に編集元項目(fruit)を取ります。
Apple.cs
のExpirationDate
がこちらに当てはまります。
MapFrom
メソッドの => の先で編集元項目(fruit)から計算します。
今回はFruit.cs
のExpirationDate
から3日を引いた値を転送しています。
(4) BrandCodeを元に編集 : ValueResolver
.ForMember
メソッドの引数に編集先項目(apple)を取り、ResolveUsing
メソッドの型に編集用のValueResolver
を取ります。
Apple.cs
のBrandName
がこちらに当てはまります。
ResolveUsing
メソッドを使うためにはValueResolver
の実装としてAppleBrandNameResolver
を用意します。
AppleBrandNameResolver
はIValueResolver
を実装する必要があり、1つ目の型に編集元項目(Fruit)、2つ目の型に編集先項目(Apple)、3つ目の型に設定する項目の型を設定します。
今回はBrandCode
が「111」の場合に「ふじ」、「222」の場合に「ジョナゴールド」、その他の場合は「その他の品種」と返すようにif文で条件を設定しています。
(5) 固定値転送 : UseValue
.ForMember
メソッドの引数に編集先項目(fruit)を取り、UseValue
メソッドの引数に固定値として設定する値を取ります。
Apple.cs
のPrice
がこちらに当てはまります。
今回は固定値120を転送しています。
##3. 使い方
作成したAppleMappingProfile.cs
を使うためには以下のようにして呼び出します。
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<AppleMappingProfile>();
});
var mapper = config.CreateMapper();
var apple = mapper.Map<Apple>(fruit);
##4. まとめ
以上が今回私が学習したAutoMapper
の編集機能です。
最初は自分がQiitaに記事を投稿するとは思ってもみませんでしたが、現場リーダーの強要すすめで時間を取っていただき挑戦することができました。
記事の作成にあたり多くのことを教えていただき、本当にありがとうございます。
自分の理解を深めるためにメモを兼ねて書いた記事ですが、自分と同様プログラミングを始めたばかりの方やAutoMapper
をこれから使ってみようという方に読んでいただけますと幸いです。