現在、SQL Server からデータを読み取り、Excel ファイルを出力するアプリケーションを作っています。社内ツールなのですが、元になるデータが複雑かつ大量であるため、操作効率を重視して、ウェブアプリケーションではなくデスクトップアプリケーションです。そこで、開発環境として .NET Framework 2.0 を利用して C# で開発しています。

sourcecode language=”

S2Container.NETS2Dao.NETを利用することにし、サンプル集も公開されていたので、それを参考にして作ることにしました。サンプルに従い、アプリケーションは

  • Presentation層
  • Service層
  • Domain層

の3つからなるレイヤアーキテクチャを採用しています。使用するコンポーネントはS2Container.NET、S2Dao.NET、Quill、S2Form、S2Windows.NET、S2Unit.NET、そして本エントリのタイトルもあるS2Dxo.NETです。

はてなキーワードいわく、Dxoとは

Data eXchange Objectの略。プレゼンテーションモデルとドメインモデルを相互変換するオブジェクト。ライブラリにS2Dxoなどがある。

です。S2Dxoを利用すると、インタフェース定義だけでDxoを作れて大変便利なのですが、やはり標準で提供されている変換だけでは対応しきれない場合があります。例えば、データベース上は整数値で管理している項目を、画面上ではその値が示す意味を文字列で見せたいような場合、どうしても独自の変換が必要になります。

このような場合、S2Dxoの.NET版であるS2Dxo.NETではどうすれば良いのでしょう。サイトに説明はありませんでしたが、S2Dxo.NETのソースを読むと、独自の変換クラスを実装すれば、変換ルールを追加できそうです。以下、実装例です。

携帯電話を表すドメインモデルクラスMobilePhoneDtoを、表示用のMobilePhonePageに変換するDxoを作る想定です。MobilePhoneDtoにはキャリアを表すint型のCarrierID属性があるとし、MobilePhonePageはキャリア名を画面に表示するためのstring型のCarrierName属性があるとします。このような場合、まず独自の変換クラスを作ります。変換クラスは Seasar.Dxo.Converter.AbstractPropertyConverterを継承すればよいよいです。S2Dxo.NETのソースを見ると、Seasar.Dxo.Converter.Impl以下に様々な変換クラスの実装があったので、参考にすればよいです。

using Seasar.Dxo.Converter;
namespace Example.Logics.Dxo.Converter.Impl
{
    /// 
    /// キャリアIDをキャリア名に変換するためのコンバータクラス
    /// 
    public class CarrierConverter : AbstractPropertyConverter
    {
        /// 
        /// キャリア名
        /// 
        private static class CarrierName
        {
            public const string DOCOMO = "DoCoMo";
            public const string AU = "au";
            public const string SOFTBANK = "SoftBank";
        }
        /// 
        /// オブジェクトのプロパティを任意の型に変換します
        /// (抽象メソッドは派生クラスで必ずオーバライドされます)
        /// 
        /// 変換元のオブジェクト
        /// 変換先のオブジェクト
        /// 変換先のオブジェクトに期待されている型
        /// bool 変換が成功した場合にはtrue
        protected override bool DoConvert(object source, ref object dest, System.Type expectType)
        {
            // int 以外なら変換不能
            if (!(source is int)) return false;
            switch ((int)source)
            {
                case 0:
                    dest = CarrierName.DOCOMO;
                    return true;
                case 1:
                    dest = CarrierName.AU;
                    return true;
                case 2:
                    dest = CarrierName.SOFTBANK;
                    return true;
                default:
                    return false;
            }
        }
    }
}

以上が変換クラスです。そして、Dxoのインタフェース定義において、ConversionRule属性で変換クラスを以下のように指定します。

using Seasar.Dxo.Annotation;
using Example.Logics.Dto;
using Example.Logics.Page;
using Example.Logics.Dxo.Converter.Impl;
namespace Example.Logics.Dxo
{
    public interface IMobilePhoneDxo
    {
        [ConversionRule(PropertyName = "CarrierID",
                        TargetPropertyName = "CarrierName",
                        PropertyConverter = typeof(CarrierConverter))]
        MobilePhonePage ConvertToMobilePhonePage(MobilePhoneDto site);
        void ConvertPageToMobilePhone(MobilePhonePage page, MobilePhoneDto site);
    }
}

こんな感じです。これで IMobilePhoneDxo にインジェクトされるDxoオブジェクトを使えば、MobilePhoneDtoを画面表示用のMobilePhonePageに変換することができました。

以上