J'ai une application ASP.NET MVC, qui utilise un service de requête pour obtenir des données et un service de commande pour envoyer des commandes. Ma question concerne la partie commande.
Si une demande arrive, le service de commande utilise un répartiteur de commande qui acheminera la commande vers son gestionnaire de commandes désigné. Ce gestionnaire de commandes valide d'abord la commande et si tout est acceptable, il exécute la commande.
Exemple concret: AddCommentToArticleCommandHandler reçoit un AddCommentToArticleCommand, qui a un ArticleId, CommentText et EmailAddress.
Première; la validation doit avoir lieu, comme: - vérifier si l'article existe - vérifier si l'article n'est pas fermé - vérifier si le texte du commentaire est rempli et entre 20 et 500 caractères - vérifier si l'adresse e-mail est remplie et a un format valide.
Je me demande où mettre cette validation?
1 / dans le gestionnaire de commandes lui-même. Mais alors, il ne peut pas être réutilisé dans d'autres gestionnaires de commandes.
2 / dans l'entité de domaine. Mais comme une entité de domaine ne connaît pas les référentiels ou les services, elle ne peut pas effectuer la validation nécessaire (ne peut pas vérifier si un article existe). Mais d'un autre côté, si l'entité ne contient pas de logique, alors elle devient un simple conteneur de données, qui ne suit pas les principes DDD.
3 / le gestionnaire de commandes utilise des validateurs, de sorte que la validation peut être réutilisée dans d'autres gestionnaires de commandes.
4 / Autres mécanismes?
Je cherche la chaîne de responsabilités pour cet exemple particulier et quels objets (entités, référentiels, ...) y jouent un rôle.
Avez-vous des idées sur la façon dont vous implémenteriez cela, depuis le gestionnaire de commandes jusqu'aux référentiels?
Réponses:
Je pense que vous devez séparer deux types de validation dans ce cas; validation de domaine et validation d'application .
La validation d'application est ce que vous avez lorsque vous vérifiez que la propriété de commande «texte» est comprise entre 20 et 200 caractères; vous validez donc cela avec l'interface graphique et avec un validateur de modèle de vue qui s'exécute également sur le serveur après un POST. Il en va de même pour le courrier électronique (btw, j'espère que vous vous rendez compte qu'un courrier électronique tel que `32.d +" Hello World .42 "@ mindomän.local" est valide selon la RFC).
Ensuite, vous avez une autre validation; vérifiez que cet article existe - vous devez vous poser la question de savoir pourquoi l'article ne devrait pas exister s'il existe en effet une commande envoyée depuis l'interface graphique qui consiste à y attacher un commentaire. Votre interface graphique a-t-elle finalement été cohérente et vous disposez d'une racine agrégée, l'article, qui peut être physiquement supprimée du magasin de données? Dans ce cas, vous déplacez simplement la commande dans la file d'attente des erreurs car le gestionnaire de commandes ne parvient pas à charger la racine agrégée.
Dans le cas ci-dessus, vous auriez une infrastructure qui gère les messages incohérents - ils réessayeraient par exemple le message 1 à 5 fois, puis le déplaceraient dans une file d'attente empoisonnée où vous pourriez inspecter manuellement la collection de messages et renvoyer ceux qui sont pertinents. C'est une bonne chose à surveiller.
Alors maintenant, nous avons discuté:
Validation des candidatures
Files d'attente racine + poison agrégées manquantes
Qu'en est-il des commandes qui ne sont pas synchronisées avec le domaine? Peut-être avez-vous une règle dans la logique de votre domaine qui dit qu'après 5 commentaires sur un article, seuls les commentaires en dessous de 400 caractères sont autorisés, mais un gars était trop en retard avec le 5ème commentaire et devait être le 6ème - GUI ne l'a pas saisi car il n'était pas cohérent avec le domaine au moment où il envoyait sa commande - dans ce cas, vous avez un «échec de validation» dans le cadre de votre logique de domaine et vous renverriez l'événement d'échec correspondant.
L'événement peut prendre la forme d'un message sur un courtier de messages ou sur votre répartiteur personnalisé. Le serveur Web, si l'application est monolithique, pourrait écouter de manière synchrone à la fois un événement de réussite et l'événement d'échec mentionné et afficher la vue / partielle appropriée.
Souvent, vous avez un événement personnalisé qui signifie l'échec de nombreux types de commandes, et c'est cet événement auquel vous vous abonnez du point de vue du serveur Web.
Dans le système sur lequel nous travaillons, nous faisons des requêtes-réponses avec des commandes / événements sur un bus de messages MassTransit + RabbitMQ + un courtier et nous avons un événement dans ce domaine particulier (modélisation d'un flux de travail en partie) qui est nommé
InvalidStateTransitionError
. La plupart des commandes qui tentent de se déplacer le long d'une arête dans le graphique d'état peuvent provoquer cet événement. Dans notre cas, nous modélisons l'interface graphique d'après un paradigme finalement cohérent, et nous envoyons donc l'utilisateur vers une page de `` commande acceptée '' et ensuite laissons les vues du serveur Web se mettre à jour passivement via les abonnements aux événements. Il convient de mentionner que nous faisons également du sourcing d'événements dans les racines agrégées (et le ferons également pour les sagas).Donc, vous voyez, une grande partie de la validation dont vous parlez sont en fait des validations de type application, et non une logique de domaine réelle. Il n'y a aucun problème à avoir un modèle de domaine simple si votre domaine est simple mais que vous faites DDD. Cependant, au fur et à mesure que vous modélisez votre domaine, vous découvrirez que le domaine n'est peut-être pas aussi simple qu'il l'a été au départ. Dans de nombreux cas, la racine / entité agrégée peut simplement accepter un appel de méthode provoqué par une commande et changer une partie de son état sans même effectuer de validation - en particulier si vous faites confiance à vos commandes comme vous le feriez si vous les validiez sur le serveur Web qui vous contrôlez.
Je peux recommander de regarder les deux présentations sur DDD de la Norwegian Developer Conference 2011 ainsi que la présentation de Greg à Öredev 2010 .
À la vôtre, Henke
la source
EDIT: lien WaybackMachine: http://devlicio.us/blogs/billy_mccafferty/archive/2009/02/17/a-response-to-validation-in-a-ddd-world.aspx
Il n'y a pas de réponse.
la source