La validation doit être effectuée dès que possible.
La validation dans n’importe quel contexte, que ce soit un modèle de domaine ou tout autre moyen d’écrire un logiciel, doit servir à CE QUE vous voulez valider et à quel niveau vous vous trouvez actuellement.
Sur la base de votre question, je suppose que la réponse serait de scinder la validation.
La validation de propriété vérifie si la valeur de cette propriété est correcte, par exemple lorsqu'une plage comprise entre 1 et 10 est spécifiée.
La validation d'objet garantit que toutes les propriétés de l'objet sont valides conjointement. Par exemple, BeginDate est avant EndDate. Supposons que vous lisiez une valeur du magasin de données et que BeginDate et EndDate soient initialisés à DateTime.Min par défaut. Lors de la définition de BeginDate, il n'y a aucune raison d'appliquer la règle "doit être avant EndDate", car cela ne s'applique pas ENCORE. Cette règle doit être vérifiée APRÈS que toutes les propriétés aient été définies. Ceci peut être appelé au niveau racine agrégé
La validation doit également être effectuée sur l'entité agrégée (ou racine agrégée). Un objet Order peut contenir des données valides, tout comme ses OrderLines. Mais une règle de gestion stipule qu’aucun ordre ne peut dépasser 1 000 dollars. Comment appliqueriez-vous cette règle dans certains cas, cela EST autorisé. vous ne pouvez pas simplement ajouter une propriété "ne pas valider le montant" car cela entraînerait des abus (tôt ou tard, peut-être même vous, juste pour obtenir cette "vilaine demande" de la route).
Ensuite, il y a validation au niveau de la couche de présentation. Allez-vous vraiment envoyer l'objet sur le réseau, sachant qu'il échouera? Ou allez-vous épargner ce burdon à l'utilisateur et l'informer dès qu'il entrera une valeur invalide. Par exemple, la plupart du temps, votre environnement DEV sera plus lent que la production. Souhaitez-vous attendre 30 secondes avant d’être informé de "vous avez de nouveau oublié ce champ pendant un autre test", en particulier lorsqu’un bug de production doit être corrigé alors que votre patron vous respire?
La validation au niveau de la persistance est supposée être aussi proche que possible de la validation de la valeur de la propriété. Cela aidera à éviter les exceptions avec la lecture des erreurs "NULL" ou "Valeur invalide" lors de l'utilisation de mappeurs de tout type ou de lecteurs de données anciens L'utilisation de procédures stockées résout ce problème, mais nécessite d'écrire AGAIN et de l'exécuter AGAIN. Et les procédures stockées sont le domaine d'administration de la base de données, alors n'essayez pas de faire son travail aussi bien (ou pire, dérangez-le avec ce «médiocre choix pour lequel il n'est pas payé».
pour le dire avec quelques mots célèbres "ça dépend", mais au moins vous savez maintenant POURQUOI ça dépend.
J'aimerais pouvoir regrouper tout cela dans un seul endroit, mais malheureusement, cela ne peut être fait. Cela créerait une dépendance sur un "objet Dieu" contenant TOUTES les validations pour TOUTES les couches. Vous ne voulez pas aller dans cette voie sombre.
Pour cette raison, je ne lance que des exceptions de validation au niveau de la propriété. Tous les autres niveaux, j'utilise ValidationResult avec une méthode IsValid pour rassembler toutes les "règles brisées" et les transmettre à l'utilisateur dans une seule exception AggregateException.
Lors de la propagation de la pile d'appels, je les rassemble à nouveau dans AggregateExceptions jusqu'à atteindre la couche de présentation. La couche service peut envoyer cette exception directement au client dans le cas de WCF en tant qu'exception FaultException.
Cela me permet de prendre l'exception et de la scinder pour afficher les erreurs individuelles à chaque contrôle d'entrée ou de l'aplatir et de l'afficher dans une seule liste. Le choix t'appartient.
c'est pourquoi j'ai également évoqué la validation de la présentation, afin de les court-circuiter autant que possible.
Dans le cas où vous vous demandez pourquoi je dispose également de la validation au niveau de l'agrégation (ou du niveau de service si vous le souhaitez), c'est parce que je n'ai pas de boule de cristal me disant qui utilisera mes services dans le futur. Vous aurez suffisamment de difficulté à trouver vos propres erreurs pour empêcher les autres de commettre les mêmes erreurs que vous :) en saisissant des données non valides.Vous administrez l'application A, mais l'application B alimente certaines données à l'aide de votre service. Devinez qui ils demandent en premier quand il y a un bug? L’administrateur de l’application B informera volontiers l’utilisateur "il n’ya pas d’erreur de ma part, j’ai simplement introduit les données".