2014-01-20 21 views
5

Ich möchte Elemente des CQRS-Musters in meinem Projekt verwenden. Ich frage mich, ob ich es richtig mit Command and Events mache. Die Sache, die ich nicht sicher bin, ist, ob Ereignis Befehl aufrufen kann. Um besser zu zeigen, was ich tun möchte, werde ich Diagramm und Beispiel verwenden.CQRS - kann EventListener Befehl aufrufen?

Dies ist ein Beispiel:

Benutzer TripCreateCommand aufzurufen. TripCreateCommandHandler erledigt seine Arbeit und veröffentlicht nach dem Erfolg TripCreatedEvent.

Jetzt haben wir zwei Zuhörer TripCreatedEvent (die Reihenfolge der Zuhörer Ausführung spielt keine Rolle)

Erste Hörer (kann nach dem zweiten Hörer auszuführen sein):

für jeden Benutzer in trip.author.friends aufrufen zwei Befehl (die Reihenfolge der Befehle ist wichtig)

  1. PublishTripOnUserWallCommand
  2. SendNewTripEmailNotificationCommand
  3. SendNewTripPlatformNotification

Zweiter Hörer (kann vor dem ersten Zuhörer auszuführen sein):

  1. PublishTripOnUserSocials

Und das ist ein Beispieldiagramm:

enter image description here

Ist das ist ein guter Weg ? Kann EventListener Befehl aufrufen, oder sollte ich es auf andere Weise tun?

Antwort

9

Ihre Frage bezieht sich auf Mesage Driven Architecture, die mit CQRS zusammenarbeitet, aber ansonsten nicht damit zusammenhängt.

Wie auch immer, Ihr Diagramm ist fast korrekt. Der Event Subscriber/Handler (ich bevorzuge diese Terminologie) kann neue Befehle über den Servicebus senden, aber es ist keine Regel, dass Sie immer tun sollten. Ich implementiere ziemlich viele Funktionen direkt im Event-Handler, obwohl probalby sauberer und zuverlässiger wäre, um einen neuen Befehl zu senden. Es hängt wirklich davon ab, was ich machen möchte.

Beachten Sie, dass die Nachrichtenhandler (Befehle oder Ereignisse) über andere Handler nicht wissen sollten. Sie sollten über den Bus Bescheid wissen und der Bus kümmert sich um die Abwicklung. Dies bedeutet, dass die Event-Handler in Ihrer App den Bus als Abhängigkeit nehmen, den Befehl erstellen und ihn über den Bus senden. Der Ereignishandler selbst weiß nicht, welcher Befehls-Handler das Ereignis generiert hat und kann darauf "antworten".

Normalerweise werden die Befehle unabhängig voneinander gehandhabt, und Sie können die Reihenfolge nicht garantieren (es sei denn, sie werden synchron behandelt). Vielleicht möchten Sie den zweiten Befehl als Ergebnis der Behandlung des ersten Befehls ausgeben. In der Tat kann es für eine Saga der Fall sein.

AFAIK Sie reden nur über Dinge synchron zu tun, so funktioniert Ihr Ansatz in diesem Fall, aber es ist wahrscheinlich nicht skalierbar. Wenn Sie zur asynchronen Behandlung wechseln, wird dieser Ausführungsablauf unterbrochen. Aber Ihre Anwendung kann gut damit sein, nicht jeder muss Twitter sein.

Eine nachrichtengesteuerte Architektur ist nicht so einfach und in einigen Fällen (wie Sie wollen eine sofortige Antwort vom Backend) ist es ziemlich kompliziert zu implementieren, zumindest komplizierter als mit dem "Standard" -Ansatz. Vielleicht möchten Sie es für diese speziellen Fälle auf die "alte" Art und Weise tun.

Wenn Sie Bedenken hinsichtlich der Entkopplung und des Testens haben, können Sie die Dienste immer noch so entwerfen, wie sie Nachrichtenhandler waren, aber sie direkt anstelle eines Servicebusses verwenden.

+0

Vielen Dank für die Wiederholung! Skalierbarkeit ist eines der wichtigsten Dinge in meinem Projekt (ich möchte die Möglichkeit haben, meine Anwendung horizontal zu skalieren), also muss ich den Befehl definitiv asynchron verarbeiten. Ich möchte Async verwenden und erwarte von C#, dies zu tun. – mrrobot

-2

Nicht sicher, warum Sie Befehle zum Aktualisieren der Informationen auf der Benutzerwand benötigen würden. Warum sollten Sie einen View Model Updater für diese Aufgabe nicht verwenden?

Das Senden einer E-Mail kann als Befehl betrachtet werden, könnte aber auch einfach als ein weiteres View Model-Update angesehen werden.

nicht klar, was der Zweck der SendNewTripPlatformNotification ist, so kann ich nicht geben es irgendwelche Vorschläge ...

Ein Teil davon auch ein Kandidat für eine Saga sein könnte. Zweitens fehlt mir Ihre Domain im Diagramm, das sollte für die Veröffentlichung von Ereignissen verantwortlich sein, oder betrachten Sie CommandHandler als Domäne?