Ich habe eine ASP.NET MVC-Anwendung, die einen Abfragedienst zum Abrufen von Daten und einen Befehlsdienst zum Senden von Befehlen verwendet. Meine Frage betrifft den Befehlsteil.
Wenn eine Anforderung eingeht, verwendet der Befehlsdienst einen Befehls-Dispatcher, der den Befehl an den angegebenen Befehlshandler weiterleitet. Dieser Befehlshandler überprüft zuerst den Befehl und führt den Befehl aus, wenn alles akzeptabel ist.
Konkretes Beispiel: Der AddCommentToArticleCommandHandler empfängt einen AddCommentToArticleCommand mit einer ArticleId, einem CommentText und einer EmailAddress.
Zuerst; Die Validierung muss erfolgen, z. B.: - Überprüfen Sie, ob der Artikel vorhanden ist. - Überprüfen Sie, ob der Artikel nicht geschlossen ist. - Überprüfen Sie, ob der Kommentartext ausgefüllt ist und zwischen 20 und 500 Zeichen. - Überprüfen Sie, ob die E-Mail-Adresse ausgefüllt ist und ein gültiges Format hat.
Ich frage mich, wo ich diese Validierung platzieren soll.
1 / im Befehlshandler selbst. Aber dann kann es nicht in anderen Befehlshandlern wiederverwendet werden.
2 / in der Domänenentität. Da eine Domänenentität jedoch nichts über Repositorys oder Dienste weiß, kann sie die erforderliche Validierung nicht durchführen (kann nicht überprüfen, ob ein Artikel vorhanden ist). Wenn die Entität jedoch keine Logik enthält, wird sie zu einem einfachen Datencontainer, der nicht den DDD-Prinzipien folgt.
3 / Der Befehlshandler verwendet Validatoren, damit die Validierung in anderen Befehlshandlern wiederverwendet werden kann.
4 / Andere Mechanismen?
Ich suche nach der Verantwortungskette für dieses spezielle Beispiel und welche Objekte (Entitäten, Repositorys, ...) darin eine Rolle spielen.
Haben Sie Ideen, wie Sie dies implementieren würden, angefangen vom Befehlshandler bis hin zu den Repositorys?
Antworten:
Ich denke, Sie müssen in diesem Fall zwei Arten der Validierung trennen. Domänenvalidierung und Anwendungsvalidierung .
Die Anwendungsüberprüfung ist das, was Sie haben, wenn Sie überprüfen, ob die Befehlseigenschaft 'text' zwischen 20 und 200 Zeichen enthält. Sie validieren dies also mit der GUI und mit einem View-Model-Validator, der auch nach einem POST auf dem Server ausgeführt wird. Gleiches gilt für E-Mails (übrigens hoffe ich, dass Sie feststellen, dass eine E-Mail wie `32.d +" Hello World .42 "@ mindomän.local" laut RFC gültig ist).
Dann haben Sie eine weitere Validierung; Überprüfen Sie, ob der Artikel vorhanden ist. Sie müssen sich die Frage stellen, warum der Artikel nicht vorhanden sein sollte, wenn tatsächlich ein Befehl von der GUI gesendet wird, mit dem ein Kommentar angehängt werden soll. War Ihre GUI schließlich konsistent und Sie haben einen aggregierten Stamm, den Artikel, der physisch aus dem Datenspeicher gelöscht werden kann? In diesem Fall verschieben Sie den Befehl einfach in die Fehlerwarteschlange, da der Befehlshandler den aggregierten Stamm nicht laden kann.
In dem oben genannten Fall hätten Sie eine Infrastruktur, die Giftnachrichten verarbeitet. Sie würden beispielsweise die Nachricht 1-5 Mal wiederholen und sie dann in eine Poision-Warteschlange verschieben, in der Sie die Sammlung von Nachrichten manuell überprüfen und die relevanten Nachrichten erneut versenden könnten. Es ist eine gute Sache zu überwachen.
Jetzt haben wir also Folgendes besprochen:
Anwendungsvalidierung
Fehlende Gesamtwurzel + Giftwarteschlangen
Was ist mit Befehlen, die nicht mit der Domäne synchron sind? Vielleicht haben Sie eine Regel in Ihrer Domain-Logik, die besagt, dass nach 5 Kommentaren zu einem Artikel nur Kommentare mit weniger als 400 Zeichen zulässig sind, aber ein Typ war mit dem 5. Kommentar zu spät und musste der 6. sein - die GUI hat es nicht verstanden, weil Es stimmte nicht mit der Domäne überein, als er seinen Befehl sendete. In diesem Fall haben Sie einen 'Validierungsfehler' als Teil Ihrer Domänenlogik und würden das entsprechende Fehlerereignis zurückgeben.
Das Ereignis kann in Form einer Nachricht an einen Nachrichtenbroker oder Ihren benutzerdefinierten Dispatcher erfolgen. Wenn die Anwendung monolithisch ist, kann der Webserver synchron sowohl auf ein Erfolgsereignis als auch auf das erwähnte Fehlerereignis warten und die entsprechende Ansicht / den entsprechenden Teil anzeigen.
Oft haben Sie ein benutzerdefiniertes Ereignis, das für viele Befehlstypen einen Fehler bedeutet, und dieses Ereignis abonnieren Sie aus Sicht des Webservers.
In dem System, an dem wir arbeiten, führen wir eine Anfrage-Antwort mit Befehlen / Ereignissen über einen MassTransit + RabbitMQ-Nachrichtenbus + Broker durch, und wir haben ein Ereignis in dieser bestimmten Domäne (teilweise Modellierung eines Workflows), das benannt ist
InvalidStateTransitionError
. Die meisten Befehle, die versuchen, sich entlang einer Kante im Zustandsdiagramm zu bewegen, können dieses Ereignis verursachen. In unserem Fall modellieren wir die GUI nach einem schließlich konsistenten Paradigma. Daher senden wir den Benutzer an eine Seite mit dem Befehl "Akzeptiert" und lassen die Ansichten des Webservers anschließend passiv über Ereignisabonnements aktualisieren. Es sollte erwähnt werden, dass wir Event-Sourcing auch in den aggregierten Wurzeln durchführen (und dies auch für Sagen tun werden).Sie sehen also, viele der Validierungen, über die Sie sprechen, sind tatsächlich Validierungen vom Anwendungstyp, keine tatsächliche Domänenlogik. Es ist kein Problem, ein einfaches Domain-Modell zu haben, wenn Ihre Domain einfach ist, Sie aber DDD ausführen. Wenn Sie jedoch mit der Modellierung Ihrer Domain fortfahren, werden Sie feststellen, dass die Domain möglicherweise nicht so einfach ist, wie es sich zunächst herausstellte. In vielen Fällen akzeptiert der aggregierte Stamm / die aggregierte Entität möglicherweise nur einen durch einen Befehl verursachten Methodenaufruf und ändert einen Teil seines Status, ohne eine Validierung durchzuführen - insbesondere, wenn Sie Ihren Befehlen vertrauen, wie Sie es tun würden, wenn Sie sie auf dem Webserver validieren Sie kontrollieren.
Ich kann empfehlen, die beiden Präsentationen zu DDD von der norwegischen Entwicklerkonferenz 2011 und auch Gregs Präsentation auf der Öredev 2010 anzusehen .
Prost, Henke
quelle
BEARBEITEN: WaybackMachine-Link: http://devlicio.us/blogs/billy_mccafferty/archive/2009/02/17/a-response-to-validation-in-a-ddd-world.aspx
Es gibt keine Antwort.
quelle