Question

J'ai un modèle de domaine ignorant de persistance qui utilise des référentiels abstraits pour charger des objets de domaine. La mise en œuvre concrète de mes dépôts (la couche d'accès aux données (DAL)) utilise Entity Framework pour extraire des données à partir d'une base de données SQL Server. La base de données a des contraintes de longueur sur un grand nombre de ses colonnes varchar. Maintenant, imaginez que j'ai la classe de domaine suivant:

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; }
}

Et un référentiel abstrait défini comme suit:

public abstract class CaseRepository
{
    public abstract void CreateCase(Case item);
    public abstract Case GetCaseById(int id);
}

La colonne [text] de la table en sqlserver est défini comme nvarchar(100)

Maintenant, je sais que je l'ai mentionné que ma classe de domaine (Case) était la persistance ignorant, néanmoins, je pense qu'il est faux qu'il permet pour les valeurs du paramètre text qui ne peut pas en fin de compte être sauvé par ma mise en œuvre du référentiel concret, car le cadre de l'entité jetteront une exception lors de l'attribution de la propriété text au cadre de l'entité classe générée quand il est plus de 100 caractères. J'ai donc décidé que je souhaite vérifier cette contrainte dans le modèle de domaine, car cela me permet de vérifier la validité des données avant de tenter de transmettre à la DAL, et rendant ainsi le rapport d'erreurs plus centrée sur l'objet de domaine. Je suppose que vous pourriez dire que je pouvais vérifier la la contrainte dans mon constructeur et le poseur de propriété, mais depuis que je suis des centaines de classes qui ont tous les mêmes contraintes que je voulais une manière plus générique pour résoudre le problème

Maintenant, la chose que je suis venu avec une classe appelée ConstrainedString, définie comme suit:

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;
        } 
    }
}

En outre, j'ai une mise en œuvre de ConstrainedString appelé String100:

public class String100 : ConstrainedString
{
    public String100(string textValue) : base(100, textValue) { }
}

conduisant ainsi à une mise en œuvre différente de Case qui ressemblerait à ceci:

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; }
}
Maintenant, ma question est

; Suis-je tenir compte de certaines classes intégrées ou d'une autre approche que je pourrais utiliser à la place? Ou est-ce une approche raisonnable?

Les commentaires et suggestions sont les bienvenus.

Merci d'avance

Était-ce utile?

La solution

Je crois que votre validation doit résider dans votre modèle de domaine. Les contraintes qui pèsent sur vos champs représentent directement une logique métier. En fin de compte, vous devez valider avant persistez de toute façon.

Autres conseils

Je pense que cela dépend de nombreux facteurs (ainsi que des préférences personnelles). Parfois, la contrainte doit faire partie de l'objet de domaine - par exemple avec des numéros de sécurité sociale / numéro de passeport ... - ceux-ci ont normalement une longueur fixe et ne peut pas varier en règle de domaine - pas une règle de persistance de données (bien que vous pourriez contraindre le db aussi bien).

Certains préfèrent ne pas avoir ce genre de contrôles dans leur modèle de domaine et ont plutôt quelque chose comme un attribut de validation sur la propriété qui peut être inspecté et exécuté externe de l'objet de domaine par un séparé validateur.

La question que vous pourriez avoir avec votre méthode (mais pas difficile de se déplacer) devient une ORM / Mapper - si vous utilisez un -. De savoir comment mapper une chaîne / de la db à votre ConstrainedString

Le ConstrainedString pourrait ne pas contourner la question de l'objet de domaine ayant d'informations supplémentaires sur la contrainte qu'il pourrait avoir besoin de construire le ConstrainedString

Si vous modifiez les contraintes d'une affaire, il est logique que vous auriez à faire une nouvelle - vous avez modifié le contrat, et l'ancien code ne saurez plus si elle est de répondre aux exigences ou non

Au lieu de se soucier de ce que votre dépôt sera ou ne permettra pas, définir permettrez dans votre classe, et assurez-vous que vous trouver un moyen de travailler avec un dépôt que vous changez dans l'avenir. Vous êtes propriétaire de votre API - vos dépendances ne pas

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top