質問
私は、ロード・ドメイン・オブジェクトに抽象的なリポジトリを使用して永続無知なドメインモデルを持っています。 私のリポジトリの具体的な実装(データアクセス層(DAL))は、SQL Serverデータベースからデータをフェッチするために、エンティティフレームワークを使用しています。 データベースは、そのvarchar列の多くの長さの制約があります。 今、私は次のドメインクラスを持っていることを想像します:
public class Case
{
public Case(int id, string text)
{
this.Id = id;
this.Text = text;
}
public int Id { get; private set; }
public string Text { get; set; }
}
そして、次のように定義された抽象リポジトリます:
public abstract class CaseRepository
{
public abstract void CreateCase(Case item);
public abstract Case GetCaseById(int id);
}
のSQLServerのテーブルの[text]
列がnvarchar(100)
今、私は自分のドメインクラス(Case
)は無知な持続性、それにもかかわらず、私はできること間違っていると感じたと指摘していることを知っています
最終的には、エンティティフレームワークので、私の具体的なリポジトリの実装により保存することはできませんtext
パラメータの値について
それが100文字より長いとき、エンティティフレームワーク生成されたクラスにtext
プロパティを割り当てるときに例外がスローされます。
私はこれは私がしようとする前に、データの妥当性を確認することができますので、ドメインモデルでは、この制約を確認したいことを私が決定しましたので、
DALの上でそれを渡すため、ドメインオブジェクトへのエラー報告をより重視すること。私はあなたが私はちょうどチェックすることができると主張することができると思います
私のコンストラクタで、プロパティセッターに制約が、私はクラスの数百を持っているので、すべては私が望んでいた同様の制約を持っていること
は今、私が作ってみたという事は、次のように定義され、ConstrainedString
と呼ばれるクラスであります
public abstract class ConstrainedString
{
private string textValue;
public ConstrainedString(uint maxLength, string textValue)
{
if (textValue == null) throw new ArgumentNullException("textValue");
if (textValue.Length > maxLength)
throw new ArgumentException("textValue may not be longer than maxLength", "textValue");
this.textValue = textValue;
this.MaxLength = maxLength;
}
public uint MaxLength { get; private set; }
public string Value
{
get
{
return this.textValue;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
if (value.Length > this.MaxLength) throw new ArgumentException("value cannot be longer than MaxLength", "value");
this.textValue = value;
}
}
}
また私はConstrainedString
と呼ばれるString100
の実装を持っています:
public class String100 : ConstrainedString
{
public String100(string textValue) : base(100, textValue) { }
}
は、このように次のようになりCase
の異なる実装につながります
public class Case
{
public Case(int id, String100 text)
{
this.Id = id;
this.Text = text;
}
public int Id { get; private set; }
public String100 Text { get; set; }
}
今、私の質問は、私はいくつかの組み込みのクラスや、私が代わりに使用できることを他のいくつかのアプローチ見下ろすだろうか?それとも、これは合理的なアプローチです?
任意のコメントや提案は大歓迎です。
事前にありがとうございます。
解決
私はあなたの検証がドメインモデルに存在すべきであると考えています。あなたのフィールド上の制約は、直接いくつかのビジネス・ロジックを表します。最終的にあなたがとにかく存続する前に検証する必要があります。
他のヒント
私は、これは多くの要因に依存だと思う(だけでなく、いくつかの個人的な好み)。これらは通常、固定長さを有し、ドメイン原則として変更することはできません - - ないデータの永続化ルール(あなたはデシベルを制約するかもしれませんが...社会保障番号/パスポート番号の例えば - 時々制約は、ドメインオブジェクトの一部を形成する必要があります同様)。
いくつかは、自分のドメインモデルに小切手のこれらの並べ替えを持って、代わりに別々のバリデータによってドメインオブジェクトから点検し、外部の実行可能なプロパティの検証属性のようなものを持っていないことを好むます。
(周りを取得することは困難ではないが)問題は、あなたはどのORM /マッパーを取得しているあなたの方法を持っているかもしれません - あなたは1を使用している場合 - あなたのConstrainedStringにDBから/への文字列をマッピングする方法を知っています<。 / P> それはConstrainedString
を構築する必要がある場合がありますように、ConstrainedStringは、制約に関する追加情報を持つドメインオブジェクトの問題を回避しない場合があります
は、それはあなたが新しいものを作るために持っていないだろうという理にかなって - 。あなたが契約を変更した、そしてそれが要件を満たすか、いない場合は、古いコードは、もはや知ることができます。
代わりにあなたのリポジトリがまたは、はは、あなたのクラスに許可するかを定義し、あなたは内に変更することを任意のリポジトリで作業するための方法を見つけることを確認して許可しないだろう何の心配の未来。あなたのAPIを所有して - あなたの依存関係にはありません。
。