Um den Code über die Ticketbenachrichtigungssysteme zu überarbeiten, habe ich einen Doctrine-Listener erstellt:
%Vor%Das Ziel besteht darin, Benachrichtigungen zu versenden, wenn ein Ticket oder eine TicketMessage-Entität über Mail, Slack und interne Benachrichtigungen mit Doctrine SQL erstellt oder aktualisiert wird.
Ich hatte bereits ein zirkuläres Abhängigkeitsproblem mit Doctrine, also habe ich den Entity Manager stattdessen aus den Event-Args eingefügt:
%Vor% Der Manager wird vom TicketNotificationListener
Die Webanwendung funktioniert, aber wenn ich versuche, einen Befehl wie doctrine:database:drop
auszuführen, habe ich Folgendes:
Aber das betrifft die Anbieterdienste.
Wie löst man das? Warum habe ich diesen Fehler nur bei cli?
Danke.
IMHO mischt ihr hier zwei verschiedene Konzepte:
TicketWasClosed
zum Beispiel) PostPersist
zum Beispiel) Das Ereignissystem von Doctrine soll sich in den Persistenzfluss einklinken, um Dinge zu behandeln, die direkt mit dem Speichern und Laden aus der Datenbank zusammenhängen. Es sollte für nichts anderes verwendet werden.
Für mich sieht es so aus, als ob Sie vorgehen wollen:
Wenn ein Ticket geschlossen wurde, senden Sie eine Benachrichtigung.
Das hat nichts mit Doktrin oder Persistenz im Allgemeinen zu tun. Was Sie brauchen, ist ein anderes Ereignissystem für Domain-Ereignisse.
Sie können weiterhin den EventManager von Doctrine verwenden. Stellen Sie jedoch sicher, dass Sie eine zweite Instanz erstellen, die Sie für Domain-Ereignisse verwenden.
Sie können auch etwas anderes verwenden. Symfonys EventDispatcher zum Beispiel. Wenn Sie das Symfony-Framework verwenden, gilt dasselbe auch hier: Verwenden Sie keine Symfony-Instanz, erstellen Sie Ihre eigene für Domain-Events.
Persönlich mag ich SimpleBus , das Objekte als Ereignisse anstelle einer Zeichenfolge (mit einem Objekt als "Argumente") verwendet. Es folgt auch den Message Bus- und Middleware-Mustern, die viel mehr Optionen für die Anpassung bieten.
PS: Es gibt viele wirklich gute Artikel zu Domain-Events. Google ist dein Freund:)
Beispiel
Normalerweise werden Domänenereignisse in Entitäten selbst aufgezeichnet, wenn eine Aktion für sie ausgeführt wird. Also hätte die Entität Ticket
eine Methode wie:
Dies stellt sicher, dass die Entitäten in vollem Umfang für ihren Zustand und ihr Verhalten verantwortlich sind und ihre Invarianten schützen.
Natürlich brauchen wir einen Weg, um die aufgezeichneten Domain Events aus der Entity zu entfernen:
%Vor%Von hier aus wollen wir wahrscheinlich 2 Dinge:
Mit Doctrine ORM können Sie einen Listener für Doctrines OnFlush
-Ereignis abonnieren, das recordedEvents()
für alle gereinigten Entitäten (zum Sammeln der Domain-Ereignisse) und PostFlush
, die diese an einen Dispatcher übergeben können, aufruft / Herausgeber (nur wenn erfolgreich).
SimpleBus bietet eine DoctrineORMBridge , die diese Funktionalität bereitstellt.
Hatte in letzter Zeit das gleiche architektonische Problem, vorausgesetzt, Sie verwenden Doctrine 2.4+
, ist es am besten, das EventSubscriber
nicht zu verwenden (was für alle Events auslöst), aber EntityListeners
für die beiden von Ihnen erwähnten Entitäten / p>
Unter der Annahme, dass das Verhalten beider Entitäten gleich sein sollte, könnten Sie sogar einen Listener erstellen und für beide Entitäten konfigurieren. Die Annotation sieht so aus:
%Vor% Danach können Sie die Klasse TicketNotificationListener
erstellen und eine Service-Definition den Rest erledigen lassen:
Sie brauchen hier vielleicht nicht einmal den Entity Manager, da die Entity selbst über die Methode postPersist
direkt verfügbar ist:
Weitere Informationen zu Doctrine-Entity-Listenern: Ссылка
Tags und Links php dependency-injection symfony doctrine2