質問

私は、ロード・ドメイン・オブジェクトに抽象的なリポジトリを使用して永続無知なドメインモデルを持っています。 私のリポジトリの具体的な実装(データアクセス層(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を所有して - あなたの依存関係にはありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top