4

バックグラウンド

ドメインモデルが「中心」にあり、インフラストラクチャの具体的な実装、特に具体的なリポジトリが周辺にあることを規定するJeffrey Palermo の Onion Architectureモデル ( Hexagonal Architectureに類似) が好きです。

ここに画像の説明を入力

だから私はドメインモデルを持っているとしましょう:

//https://libphonenumber.codeplex.com/
using libphonenumber;

namespace MyApplication.Domain
{
    public class Speaker
    {
         public virtual string Name {get;set;}
         public virtual PhoneNumber PhoneNumber {get;set;}
    }
}

次に、このドメイン モデルを他のチームに公開する必要があります。

  • UI チームは、いくつかのデータ検証属性とカスタム JSON シリアライゼーション属性を追加したいと考えています。
  • インフラストラクチャ チームは、サード パーティのデータベース実装から XML シリアライゼーション属性といくつかのカスタム属性を追加したいと考えています。
  • パブリック API チームは、仮説として WCF 属性を追加したいと考えています。

すべてのチームに自分の属性を自分のドメイン モデルに追加する自由を与えたくありません。 特に、「レイヤー固有の」依存関係をすべて自分のモデル アセンブリに追加してほしくないのです

また、このケースは、私自身でサードパーティの「ドメイン モデル」を使用しているため、より複雑になっています (この場合、Google のLibPhoneNumberを使用して電話番号を処理しています)。

理想的には、次のような独自のラッパー クラスを作成する必要があります。

using MyApplication.Domain;
namespace MyApplication.UI.DomainWrappers
{
    public class UISpeaker
    {
         private Speaker _speaker;
         public class UISpeaker(Speaker speaker = null)
         {
             _speaker = speaker ?? new Speaker();
         }

         [Required]
         public virtual string Name {
            get{ return _speaker.Name; }
            set{ _speaker.Name = value; }
         }

         [Required]
         public virtual PhoneNumber PhoneNumber {
            get{ return _speaker.PhoneNumber ; }
            set{ _speaker.PhoneNumber = value; }
         }

         //Conversion operators
         public static implicit operator UISpeaker(Speaker s)
         {
           return new UISpeaker(s);
         }

         public static implicit operator Speaker(UISpeaker s)
         {
           return s._speaker;
         }             
    }
}

質問

クラスの作成と維持UISpeakerは骨の折れる作業であり、退屈な定型コードです。

ドメインモデルを直接編集させずに、各チームが追加したい属性を追加するより良い方法はありますか? または、これらのラッパー クラスを生成するのに役立つツールがありますか (おそらくFodyT4 Templatesのような製織ツールを考えていましたが、このユース ケースで役立つかどうかを知るには、どちらにも精通していません)。

リサーチ

Stackoverflow を調べたところ、同様の質問がいくつか見つかりましたが、探している範囲をすべて満たすものはありませんでした。

4

1 に答える 1

2

これらのオプションを使用して、ジョブを簡素化できます。

  • メタデータ クラス
  • オブジェクトからオブジェクトへのマッパー
  • コード生成

メタデータ クラス

メタデータ クラスを作成し、データ アノテーションや検証属性などの属性をそれらのメタデータ クラスに追加してから、 を使用してこれらのメタデータ クラスをメイン ドメイン クラスに関連付けることができますAssociatedMetadataTypeTypeDescriptionProvider。このようなメタデータ クラスは単なる属性コンテナーであり、型記述子メカニズムを使用してメイン クラスに属性を追加します。

たとえば、この方法でモデルのメタデータ クラスを登録し、利益を得るすべてのインフラストラクチャがTypeDescriptorモデルのメタデータ属性を参照できるようにすることができます。

var provider = new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Model), 
                                                                 typeof(ModelMetadata));
TypeDescriptor.AddProvider(provider, typeof(Model));

オブジェクトからオブジェクトへのマッパー

ビューモデル、ビジネスモデル、およびドメインモデルを異なるレイヤーに配置し、各レイヤーに必要な属性でそれらを装飾し、オブジェクトからオブジェクトへのマッパーなどを使用して、AutoMapperこれらのクラスを相互にマッピングするタスクを簡素化できます。

AutoMapper は、オブジェクト間マッパーです。オブジェクト間マッピングは、あるタイプの入力オブジェクトを別のタイプの出力オブジェクトに変換することによって機能します。AutoMapper を興味深いものにしているのは、型 A を型 B にマップする方法を理解するための面倒な作業をなくすためにいくつかの興味深い規則を提供していることです。型 B が AutoMapper の確立された規則に従う限り、2 つの型をマップするために必要な構成はほとんどゼロです。

コード生成

一部のコード生成ツールを使用すると、メタデータ クラスまたはビュー モデル クラスをより簡単に作成できます。たとえば、T4 テンプレートのようなコード生成メカニズムを使用して、ラッパー クラスを簡単に作成できます。

Visual Studio では、T4 テキスト テンプレートは、テキスト ブロックと、テキスト ファイルを生成できる制御ロジックを組み合わせたものです。制御ロジックは、Visual C# または Visual Basic でプログラム コードのフラグメントとして記述されます。生成されるファイルは、Web ページ、リソース ファイル、任意の言語のプログラム ソース コードなど、任意の種類のテキストにすることができます。

于 2016-01-15T21:39:21.517 に答える