お知らせ
2019年8月24日
C#ネタ その③ リフレクションしながら値変換するコンバータ属性の作成
リフレクションを用いてDTO変換を行いながら特定の項目のみ値変換を行う方法をご紹介します。
例えば、機能間で共通のSQLを使用していて、ある機能では「削除フラグ」を0、1のフラグとして使用、
他の機能では一覧に表示する際、「削除フラグ」を「削除済み」「未削除」と名称を変えたい。
と、少々ややこしい仕様にしなければならない場面がありました。
この場合、SQL側にCASE文を書いて0だったら「未削除」等と変換しまうと、フラグとして利用することが困難になります。
SQLを二つに分けたくなかったので、DTOの属性にリフレクション中に値の変換を行うようコンバータを作成します。
まず、属性クラスを継承したコンバータの抽象クラスを用意します。
public abstract class AbstractDtoConverter : Attribute { public abstract object Convert(object _o); }
次に、上記の抽象クラスを継承したコンバータクラスを作成します。
public class DeleteFlagConverter : AbstractDtoConverter { public override object Convert(object _o) { if (_o != null) { return "1".Equals(_o as string) ? "削除済み" : "未削除"; } return _o; } }
この例では、削除フラグが1の場合に「削除済み」、0の場合は「未削除」へ変換します。
次に、DTOへコンバータを設定します。
public class TestDto { [DeleteFlagConverter] public string DeleteFlag { get; set; } }
最後に、object⇒DTOへリフレクションにて変換を行う際に、Converterを取得し実行させます。
foreach (PropertyInfo prop in item.GetType().GetProperties()) { // DTOに指定されているコンバータ属性を取得 AbstractDtoConverter abstractConverter = Attribute.GetCustomAttribute(prop, typeof(AbstractDtoConverter)) as AbstractDtoConverter; object fieldValue = prop.GetValue(item); // 属性にコンバータが設定されている場合 if (abstractConverter != null) { // コンバータを実行 fieldValue = abstractConverter.Convert(fieldValue); } Console.WriteLine(fieldValue); }
リフレクション中にPropertyInfoから属性を取得し、コンバータを起動させ値変換を行うだけの処理ですが、使い方によっては便利な場面があるかと思います。