Facebook
Twitter
Google+
Kommentare
1

Annovent – Event Dispatching

Vor kurzem „musste“ ich für ein Projekt einen Event Dispatcher bauen. Ja ich weiß, Symfony hat da einen, der eigentlich schon alles kann. Aber irgendwie hatte ich da keine Lust drauf, denn ich wollte ein paar Special-Features reinklöppeln. Damit ich aber nicht komplett das Rad neu erfinde, habe ich mich einfach an der Interface von Symfony gehalten und da etwas kompatibles gebaut.

Die Grundlagen des Event Dispatchers könnt ihr einfach auf der Symfony Components Webseite nachlesen, denn bis dorthin sind wir fast 100% kompatibel. Aber wie gesagt ich wollte Special-Features und die sehen wie folgt aus:

Namesspaces

In dem Standard-Dispatcher kann ich meine Listeners nur auf einen ganz speziellen Event hören lassen. Das war mir nicht genug, denn ich wollte auf eine Gruppe von Ereignissen reagieren. Deswegen habe ich Namespaces eingeführt und kann somit mit Platzhaltern arbeiten. In der Verwendung sieht dies dann wie folgt aus:

$dispatcher->connect('SomeComponent.MyEvent', array($listener, 'Method1'));
$dispatcher->connect('SomeComponent.*', array($listener, 'Method1'));
$dispatcher->connect('*', array($listener, 'Method2'));

Der erste Listener hört nur genau auf SomeComponent.MyEvent, der zweite auf alle Ereignisse, die von SomeComponent erzeugt werden und der dritte hört einfach auf jedes Event, das irgendwo verwendet wird.

Annotations

Auch wenn wir jetzt schon besser sind als Symfony, waren die Namespaces nicht genug. Dank der Doctrine-Implementierung zum Annotation-Handling war es kein Problem auch noch Annotations draufzusetzen. Ich habe ja vor ein paar Tagen darüber geredet und hier ist endlich der Anwendungsfall dazu:

class Listener
{
  /**
   * @Event("SomeComponent.Bar")
   * @Event("SomeComponent.Foo")
   */
  public function method1(Event $event)
  {
  }
}
$dispatcher->connectListener( new Listener );

Dieser registriere Listener würde nun auf zwei Events hören: SomeComponent.Bar und SomeComponent.Foo. Ich kann aber natürlich auch die method1 über connect wie gewohnt registrieren, man muss dieses Feature also nicht nutzen, wenn man nicht will.

Named Parameters

Irgendwie fand ich es auch noch ganz lustig mit Named Parameters zu arbeiten. Das fand ich ganz spannend, denn so muss ich nicht wissen, wie die notifacation des Events ihre Parameter mitbringt. Deswegen hab ich den Code so gebaut, das folgendes Beispiel funktioniert.

class Listener2
{
  /**
   * @Event("SomeComponent.Render")
   */
  public function method1($argument1, $foo)
  {
  }
}
$dispatcher->notify(new Event('SomeComponent.Render', array('foo' => 'bar', 'argument1' => 'arg1' ));

Zusätzlich wird immer das Event selbst als Parameter angehängt. Das System ist so gebaut, dass Parameter, die die Methode nicht kennt einfach unterschlagen werden. Fand ich kompatibler zu Erweiterungen und wenn man nun der method1 noch ein Argument $event hinzufügt, so bekommt man dort das Event und kann damit die üblichen Dinge mit machen.

So das waren meine drei Special-Features. Meiner Meinung nach fühlt sich der Dispatcher in der Handhabung gut an und ich hoffe, dass der ein oder andere ihn nutzen oder forken will.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

1 Comments

  1. Ich finde die Idee der Namespaced Events sehr gut. Auch die named Patameter sind sehr nützlich. Könntest Du die Erweiterungen nicht einfach zu Symfony bringen? Die würden profitieren.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen