La convalida deve essere eseguita il prima possibile.
La convalida in qualsiasi contesto, con il modello di dominio o con qualsiasi altro modo di scrivere software, dovrebbe servire allo scopo di ciò che si desidera validare e al livello in cui ci si trova al momento.
In base alla tua domanda, suppongo che la risposta sarebbe dividere la convalida.
-
La verifica della proprietà verifica se il valore per quella proprietà è corretto ad es. quando è previsto un intervallo tra 1-10.
-
La convalida dell'oggetto garantisce che tutte le proprietà sull'oggetto siano valide insieme l'una con l'altra. per esempio. BeginDate è prima di EndDate. Supponiamo di leggere un valore dall'archivio dati e sia BeginDate che EndDate vengono inizializzati su DateTime.Min per impostazione predefinita. Quando si imposta BeginDate, non vi è alcun motivo per applicare la regola "deve essere prima di EndDate", poiché ciò non si applica ANCORA. Questa regola deve essere verificata DOPO che tutte le proprietà sono state impostate. Questo può essere chiamato al livello radice aggregato
-
La convalida deve essere eseguita anche sull'entità aggregata (o radice aggregata). Un oggetto Order può contenere dati validi e così fa OrderLines. Ma poi una regola aziendale afferma che nessun ordine può essere superiore a $ 1.000. Come faresti applicare questa regola in alcuni casi questo è permesso. non puoi semplicemente aggiungere una proprietà "non convalidare l'importo" poiché ciò porterebbe ad abusi (prima o poi, forse anche tu, solo per ottenere questa "brutta richiesta" di mezzo).
-
dopo c'è la convalida a livello di presentazione. Invierai davvero l'oggetto sulla rete, sapendo che fallirà? O risparmierai l'utente di questo burdon e lo informerai non appena avrà inserito un valore non valido. per esempio. il più delle volte il tuo ambiente DEV sarà più lento della produzione. Ti piacerebbe aspettare 30 secondi prima di essere informato di "hai dimenticato questo campo ANCORA durante un ALTRO giro di prova", specialmente quando c'è un bug di produzione da risolvere con il tuo capo che ti respira il collo?
-
Si suppone che la convalida a livello di persistenza sia il più vicino possibile alla convalida del valore della proprietà. Ciò consentirà di evitare eccezioni con la lettura di errori "null" o "valore non valido" quando si utilizzano i programmi di mapping di qualsiasi tipo o semplici lettori di dati vecchi. L'uso di stored procedure risolve questo problema, ma richiede di scrivere nuovamente la stessa logica di valenza ed eseguirla di nuovo. E le stored procedure sono il dominio admin del DB, quindi non provare a fare il suo lavoro HIS (o peggio lo infastidisce con questo "picking nitty a cui non viene pagato".
quindi per dirlo con alcune parole famose "dipende", ma almeno ora sai perché dipende.
Vorrei poter mettere tutto questo in un unico posto, ma sfortunatamente, questo non può essere fatto. In questo modo si posizionerebbe una dipendenza da un "oggetto Dio" contenente TUTTE le convalide per TUTTI i livelli. Non vuoi percorrere quel sentiero oscuro.
Per questo motivo lancio solo eccezioni di validazione a livello di proprietà. Tutti gli altri livelli utilizzo ValidationResult con un metodo IsValid per raccogliere tutte le "regole non valide" e passarle all'utente in una singola AggregateException.
Durante la propagazione dello stack di chiamate, li raccolgo nuovamente in AggregateExceptions finché non raggiungo il livello di presentazione. Il livello di servizio può lanciare questa eccezione direttamente al client in caso di WCF come FaultException.
Questo mi consente di prendere l'eccezione e dividerlo per mostrare singoli errori ad ogni controllo di input o appiattirlo e mostrarlo in un unico elenco. La scelta è tua.
Questo è il motivo per cui ho anche menzionato la convalida della presentazione, per metterla in cortocircuito il più possibile.
Nel caso ti stia chiedendo perché ho anche la convalida a livello di aggregazione (o livello di servizio, se lo desideri), è perché non ho una sfera di cristallo che mi dice chi utilizzerà i miei servizi in futuro. Avrai abbastanza problemi a trovare i tuoi errori per impedire agli altri di fare errori li tuoi :) inserendo dati non validi.e.g. tu gestisci l'applicazione A, ma l'applicazione B invia alcuni dati usando il tuo servizio. Indovina chi chiedono prima quando c'è un insetto? L'amministratore dell'applicazione B comunicherà felicemente all'utente "non ci sono errori alla mia estremità, inserisco solo i dati".