バックグラウンド
ドメインモデルが「中心」にあり、インフラストラクチャの具体的な実装、特に具体的なリポジトリが周辺にあることを規定する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
は骨の折れる作業であり、退屈な定型コードです。
ドメインモデルを直接編集させずに、各チームが追加したい属性を追加するより良い方法はありますか? または、これらのラッパー クラスを生成するのに役立つツールがありますか (おそらくFodyやT4 Templatesのような製織ツールを考えていましたが、このユース ケースで役立つかどうかを知るには、どちらにも精通していません)。
リサーチ
Stackoverflow を調べたところ、同様の質問がいくつか見つかりましたが、探している範囲をすべて満たすものはありませんでした。
ドメイン モデルで JsonIgnore 属性を使用しない - ドメイン モデルで.NETネイティブ属性のみを使用すると結論付けられたため、Json.Net に依存する必要はありませんでした。
属性を別のアセンブリのクラスに追加する -既存の型に属性
CustomReflectionContext
を追加するために使用する方法について説明しました。これは非常にクールに見えますが、残念ながらモデルはリフレクションのためにサードパーティ コード (ORM、EF、Json.Net など) に渡されるため、ここでは機能しないと思います。DDD で個別のドメイン モデルと永続性モデルを使用する- 各レイヤーには独自のバージョンのドメイン モデルが必要であることを確認しましたが、コードの記述と保守を容易にするためのツールや戦略があるかどうかについては議論しませんでした。