2009-09-25 5 views
11

Diciamo che ho un POCO in questo modo:Devo inserire la logica di validazione in un POCO?

public class Name 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

FirstName e cognome non può essere NULL. Dovrei aggiungo in un metodo come questo:

public List<Error> Validate() 
{ 
    var errors = new List<Error>(); 

    if (String.IsNullOrEmpty(FirstName)) 
     errors.Add(new Error("FirstName", "You must fill out first name.")); 
    if (String.IsNullOrEmpty(LastName)) 
     errors.Add(new Error("LastName", "You must fill out last name.")); 
} 

dove Error è una struct che contiene un NameValueDictionary. È un buon modo di fare le cose? Posso potenzialmente vedere un problema con il repository dove qualcuno tenta di salvare questo POCO senza eseguirlo prima tramite Validate().

risposta

2

Considerare l'utilizzo di un framework di convalida orientato all'aspetto come xVal.

Invece di dover incorporare le regole di convalida direttamente nel codice, è possibile aggiungerle come attributi delle proprietà e scaricare la dipendenza. La classe sarà simile a questa:

public class Name 
{ 
    [Required] 
    public string FirstName { get; set; } 
    [Required] 
    public string LastName { get; set; } 
} 

Per rispondere più direttamente alla tua domanda, l'aggiunta di regole di convalida al vostro POCO è un modo semplice di fare le cose che funzionano, ma si può ottenere pesante da mantenere, e ti è necessario applicare l'interfaccia di convalida a tutti gli oggetti, che è il proprio mal di testa. La soluzione orientata all'aspetto è piuttosto elegante e risolve questi problemi e molti altri.

+1

Ho esaminato xVal in precedenza ma ho trovato una netta mancanza di documentazione ed esempi. Forse lo esaminerò di nuovo ora che sto usando POCO. –

+0

Ora che ci penso, come gestiresti i casi in cui hai bisogno di una convalida più avanzata, ad esempio convalidi che una stringa del percorso di file punta a un file fisico sul disco rigido? –

+0

xVal consente di creare attributi di convalida personalizzati. Ecco una pagina di esempio: http://blog.codeville.net/2009/02/27/xval-08-beta-now-released/ – womp

3

Non lo farei. I miei POCO tendono ad avere diverse convalide in base al loro contesto. "Gli oggetti My Person devono avere un indirizzo in questa applicazione, ma devono avere solo un numero di telefono in questa altra applicazione" ... è il tipo di cosa che vuoi tenere d'occhio ed essere flessibile per.

Sono un sostenitore del modello di dominio anemico poiché riutilizzavo tipicamente lo stesso dominio, ma assegna un comportamento e una convalida diversi in base al contesto (che potrebbero anche essere aree diverse della stessa applicazione).

Quando si implementano nuove funzionalità, di solito guardo la mia classe e mi pongo questa domanda: questa sembra la responsabilità di questa classe, o sarebbe più adatta per una classe con un diverso insieme di responsabilità? Chiamiamo questo controllo per "Feature Envy" e aiuta efficacemente a distinguere ciò che la classe è e non è preoccupata.

+0

Concordo moltissimo con il tuo secondo paragrafo. Questo è esattamente il motivo per cui i motori di regole sono diventati popolari. – womp

+3

I modelli di dominio anemici sono inutili. Finisci per ricodificare la stessa logica di business ovunque. È in realtà un antipattern secondo Martin Fowler. E il modello anemico non è altro che un DTO. – Andy

+1

Mentre i commenti sono vecchi, ho pensato che sarebbe stato utile aggiungere un collegamento a [ciò che Andy si sta riferendo] (http://martinfowler.com/bliki/AnemicDomainModel.html). – Derek

0

Non trovo nulla di sbagliato mettendo la convalida nel modello. Funziona bene con tutte le tecnologie di interfaccia utente di Microsoft che si aspettano che il modello possa essere chiesto se è valido o meno, e non si continua a mappare un DTO a un altro, per poi ripetere la convalida in una vista o modificare il modello (o peggio, solo mettendolo lì).

Le regole del campione sono semplici, ma spesso è necessario scrivere regole più complesse. Probabilmente dovresti controllare il framework Csla.Net.