Domanda

Ho un modello di dominio ignorante di persistenza che utilizza i repository astratti per caricare oggetti di dominio. L'attuazione concreta dei miei repository (lo strato di accesso ai dati (DAL)) utilizza Entity Framework per recuperare i dati da un database di SQL Server. Il database ha vincoli di lunghezza su un sacco di sue colonne varchar. Ora immaginate che ho la seguente classe di dominio:

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

E un archivio astratto definito come segue:

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

La colonna [text] della tabella in sqlserver è definita come nvarchar(100)

Ora so che ho detto che la mia classe di dominio (Case) era la persistenza ignorante, tuttavia, ritengo che sia sbagliato che permette per valori del parametro text che non può infine essere salvato da mia implementazione repository concreta perché l'Entity Framework sarà un'eccezione quando si assegna la proprietà text alla classe generata Entity Framework quando è più lungo di 100 caratteri. Così ho deciso che voglio controllare questo vincolo nel modello di dominio, perché questo mi permette di controllare la validità dei dati prima di tentare di trasmetterla al DAL, e rendendo così la segnalazione più centric all'oggetto dominio di errore. Credo che si potrebbe sostenere che ho potuto solo controllare la vincolo nel mio costruttore e nel setter di proprietà, ma dal momento che ho centinaia di classi che hanno tutti i vincoli simili volevo un altro modo generico per risolvere il problema

Ora, la cosa che mi è venuta in mente è una classe chiamata ConstrainedString, definito come segue:

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

Inoltre ho un'implementazione di ConstrainedString chiamato String100:

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

Così che porta a una diversa implementazione di Case che sarebbe simile a questa:

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

Ora, la mia domanda è; Sto trascurando alcune classi incorporate o qualche altro approccio che potrei usare invece? O si tratta di un approccio ragionevole?

Tutti i commenti e suggerimenti sono i benvenuti.

Grazie in anticipo

È stato utile?

Soluzione

Credo che la vostra convalida deve risiedere nel vostro modello di dominio. I vincoli sui tuoi campi rappresentano direttamente una logica di business. In definitiva è necessario convalidare prima di persistono in ogni caso.

Altri suggerimenti

Credo che questo dipende da molti fattori (come pure alcune preferenze personali). A volte il vincolo dovrebbe far parte dell'oggetto di dominio - ad esempio, con i numeri di previdenza sociale, numeri di passaporto / ... - questi normalmente hanno una lunghezza fissa e non può variare di regola di dominio - non una regola di dati di persistenza (anche se si potrebbe vincolare il db come pure).

Alcuni preferiscono non avere questo genere di controlli nel loro modello di dominio e invece hanno qualcosa di simile a un attributo di convalida sulla proprietà che può essere ispezionato ed eseguito esterno dalla oggetto di dominio da un validatore separata.

Il problema si potrebbe avere con il metodo (anche se non è difficile da ottenere intorno) è sempre qualsiasi ORM / Mapper - se si sta utilizzando uno -. Sapere come mappare una stringa da / per il db al vostro ConstrainedString

Il ConstrainedString non potrebbe aggirare il problema dell'oggetto dominio avere informazioni supplementari sul vincolo in quanto potrebbe essere necessario costruire il ConstrainedString

Se si modificano i vincoli di un caso, ha senso che avresti dovuto fare uno nuovo - hai cambiato il contratto, e il vecchio codice non sapranno se è soddisfare i requisiti o non

Invece di preoccuparsi di ciò che il repository sarà o non consentirà, definire che cosa si permetterete nella classe, e assicurarsi che trovare un modo per lavorare con qualsiasi repository di modificare al il futuro. Già il tuo API - le dipendenze no

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top