Ankündigung

Einklappen
Keine Ankündigung bisher.

Symfony Event-Dispatcher

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Symfony Event-Dispatcher

    Guten Morgen Zusammen,

    ich beschäftige mich gerade etwas mit den Event-Dispatcher und wenn ich das nun richtig verstanden habe ist es für gute Programmierung ein must-have. Nun habe ich paar Verständnis fragen dazu.

    Meine Fragen dazu, ersetzen die Methoden die sogesehen in den Events sind die eigentlichen Services oder wofür nutzt man Event Dispatcher?


    z.B. hatte ich mal /Services/CalculateService.php -> Also mein Service den ich dann über den DI im Controller nutzte.

    wird das nun durch das Event ersetzt?

    dispatcher = $this->get('event_dispatcher'); $dispatcher->dispatch('abc.calc_event', new CalculateService());

    Ich danke euch vielmals für die Erklärung.

  • #2
    Symfony hat übrigens eine sehr gute Dokumentation: https://symfony.com/doc/current/comp...ispatcher.html

    Und nein, den EventDispatcher nutzt man nicht, um etwas zu ersetzen. Einen EventDispatcher nutzt man, um eine unbekannte Anzahl an Aktionen an einem bestimmten Punkt durchzuführen.

    Beispiel: Ein Benutzer registriert sich auf der Webseite. Ich möchte ihm eine E-Mail schreiben. Und auf Slack intern etwas posten. Und auf Trello eine Card eröffnen. Und ein zweites E-Mail senden. Und mir persönlich auch ein E-Mail schreiben.

    Stell dir vor, das wäre alles in einer "Methode" integriert. Möchtest du jetzt die Slack-Benachrichtigung ausschalten (oder eine zweite hinzufügen), musst du die Registrations-Methode bearbeiten. Hast du einen EventDispatcher, fügst du entweder einen neuen Event Subscriber hinzu oder löschst/deaktivierst einen Event Subscriber. Die Registrations-Methode bleibt immer gleich.

    Schlussendlich ist das Entkopplung, Single Responsibility.
    [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

    Kommentar


    • #3
      ChristianK
      Vielen Dank Dir für die Erklärung und die Verlinkung.

      Dein sehr gut gewähltes Beispiel und da der Satz "Einen EventDispatcher nutzt man, um eine unbekannte Anzahl an Aktionen an einem bestimmten Punkt durchzuführen" haben es mir verständlich gemacht.
      Das würde bedeuten, wenn z.B. Die Registrations-Methode nur die Aufgabe hat den Benutzer hinzuzufügen, dann würde ich das ganz normal als ein Service nutzen, weil hier klar ist, dass diese Methode nichts anderes machen soll.
      Sollten aber mehrere Methoden darin verwickelt sein wie in deinem Beispiel, dann macht es Sinn es über den Event Dispatcher und Subscriberslaufen zu lassen.

      Kommentar


      • #4
        Das hängt davon ab. Prinzipiell werden Events außerhalb des eigentlichen Programmablaufs ausgeführt. Alternativ auch über ein Queuing oder in anderen Sprachen auch asynchron. Dadurch gibt es dort keinen Einfluss auf den "Hauptablauf" bzw. man muss dies speziell implementieren.

        Wenn Du nun also etwas machen willst, dass eine Fehlerehandlung erfordert (z. B. bestimmte Schritte bei einer Registrierung), dann ist dieses Konzept hier eher ungeeignet.

        Event-Driven ist ein tolles Konzept aber wie alles andere auch mit Vorsicht zu genießen.

        Kommentar


        • #5
          Zitat von yugox Beitrag anzeigen
          ChristianK
          [...]
          Sollten aber mehrere Methoden darin verwickelt sein wie in deinem Beispiel, dann macht es Sinn es über den Event Dispatcher und Subscriberslaufen zu lassen.
          Nicht ganz. Meiner Meinung nach muss der Hauptablauf (im Falle der Registration z.B. erstellen des Tupel in der DB) immer synchron bzw. direkt ersichtlich (also Controller -> Service) sein. Alles andere, was du danach noch ankoppeln möchtest, kannst du über einen EventDispatcher machen. Damit wird sofort ersichtlich, was "Pflicht" ist, und was eine Erweiterung darstellt. Das kann in Form von Pre/Post Business Rules oder ähnlichem sein. Ich setze z.B. einen BusinessProcess ein (siehe Beispiel hier: https://github.com/chrisandchris/pas...essProcess.php ), an den vor- und nach Ausführung Events angehängt werden können.

          Den Hinweis von xm22 mag grundsätzlich korrekt sein, dass Events asynchron laufen können. Das stellt allerdings auch ganz andere Anforderungen an ein Exception-Management, was nicht gerade zu vernachlässigen ist.
          [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

          Kommentar


          • #6
            Okay noch ein Versuch

            Die Registration-Methode wird wie gehabt als Service erstellt. Nun habe ich die Möglichkeit UNABHÄNGIGEN Events z.B. für das verschicken einer Email oder sonstiges mit hilfe des Dispatchers zu verwenden.

            Diese Event kann ich sogesehen auch für die Login-Methode verwenden, da sie nicht an der Registration-Methode gebunden ist und unabhängig von allem, richtig?

            Die Events die mit dem Dispatcher verwendet werden sind eigenständige Events die überall wo es einem beliebt erfolgen können.

            Kommentar


            • #7
              Ein gibt viele Möglichkeiten einen EventDispatcher zu Benutzen. Ein EventDispatcher kann auch als Extension/Plugin Provider dienen um deine Anwendung unabhängig zu erweitern. Auch kann man einen EventDispatcher dazu benutzen, wie z.B. in der Symfony Firewall um eine Aufgabe zu delegieren. Als Beispiel die Voter (https://symfony.com/doc/current/security/voters.html) von Symfony. Intern wird ein Event abgefeuert "Ich habe Objekt y und User x der Aktion y auf das Objekt ausführen möchte" Die Voter bekommen das Event und stimmen ab ob die Aktion durchgeführt werden darf.

              Kommentar


              • #8
                Wobei das nicht wirklich Events im eigentlichen Sinne sind. Es handelt sich eher um Adapter, die Bestandteil der Business-Logik werden. Es wird lediglich das Event-System von Symfony dafür verwendet. Und das funktioniert auch nur, weil diese Events synchron ausgeführt werden.

                Das klingt zwar nach Haarspalterei, ist aber ein signifikanter Unterschied.

                Schaut man sich z. B. Vertx oder Eventhandling per message queues o. ä. an - Da würde das so nicht funktionieren.

                Diese Event kann ich sogesehen auch für die Login-Methode verwenden, da sie nicht an der Registration-Methode gebunden ist und unabhängig von allem, richtig?
                Was meinst Du damit?

                Kommentar


                • #9
                  Die (innere) Arbeit des Symfony-Frameworks bzw. das Framework an sich ist auf diese Events aufgebaut, die in einer bestimmten Reihenfolge abgearbeitet werden (wobei der Name Event wahrscheinlich irreführend ist).

                  Man kann die Methoden der Events aufgreifen und erweitern oder überschreiben, bspw. onAuthenticationSuccess, um beim erfolgreichen Login eines Users eine bestimmte Aktion auszuführen, bspw. seine LoginHistory updaten.

                  Oder onKernelRequest zu einem bestimmten Zeitpunkt im Event-Stack die Request-Locale mit einer durch den User gesetzten Sprache überschreiben, um eine mehrsprachige Anwendung zu haben.

                  Kommentar


                  • #10
                    Zitat von xm22 Beitrag anzeigen
                    Wobei das nicht wirklich Events im eigentlichen Sinne sind. Es handelt sich eher um Adapter, die Bestandteil der Business-Logik werden. Es wird lediglich das Event-System von Symfony dafür verwendet. Und das funktioniert auch nur, weil diese Events synchron ausgeführt werden.
                    [...]
                    Damit bin ich nicht einverstanden. Ein Adapter würde voraussetzen, dass du den Output modifizieren kannst (eben einen Adapter zwischen zwei Formaten darstellst, wie bei einem Gartenschlauch mit 2 unterschiedlichen Anschlüssen). Du hast recht im Falle des OnKernelRequest-Event und vielen anderen (vorgebauten) Events. Es hält dich jedoch niemand davon ab, das Event-System auch für echte Events zu brauchen.

                    Ein Registrations-Event, der nur z.B. die User-ID des neuen Nutzers übergibt, stellt einen echten Event dar. Es gibt einen Input (UserID), einen Handler (z.B. das E-Mail senden), und einen Output, der vom eigentlichen Prozess vorgegeben ist (und nicht modifiziert werden kann).

                    Siehe z.B. die UML von Wikipedia zu Adapter https://en.wikipedia.org/wiki/Adapter_pattern#Structure

                    Zitat von wario Beitrag anzeigen
                    [...]
                    Man kann die Methoden der Events aufgreifen und erweitern oder überschreiben, bspw. onAuthenticationSuccess, um beim erfolgreichen Login eines Users eine bestimmte Aktion auszuführen, bspw. seine LoginHistory updaten.
                    [...]
                    Das gilt nur (und auch da nur teilweise) für Events, die Symfony mit sich bringt. Das gilt für eigene Events grundsätzlich nicht (ausser, man programmiert die Funktion).

                    Und kein Grund mit Kanonen auf Spatzen zu schiessen. Ob es dafür gleich Vertex, RabbitMQ oder was auch immer braucht, ist eine ganz andere Diskussion. Auch wenn die Architektur dafür sehr schön aussieht, Message Queues haben auch viele Pitfalls, die sich mit synchronität schon ausgleichen lassen. Zudem kann bei gutem Software-Design jederzeit zwischen asynchronen und synchronen Events gewechselt werden . Sobald man keine 100 Events pro Sekunde hat, ist das m.M.n. ein Overkill.

                    [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

                    Kommentar

                    Lädt...
                    X