2016-10-24 6 views
2

Ich muss verschiedene Metadaten-Attribute für jede Route implementieren, und eine Idee, die ich habe, ist die Attribute direkt auf jede Route anzuwenden, für einen externen Metadaten-Listener zu verwenden.Symfony: Service in Route auflösen

Zum Beispiel würde der Listener den auf der untenstehenden Route definierten Dienst (@example_title_resolver) verwenden, um in eine Form des Seitentitels aufzulösen.

example_route: 
    path:  /blah/blah 
    defaults: 
     _controller: MyBundle:MyController:index 
     meta: 
      title: 
       resolver: '@example_title_resolver' 
       value: 'Example | %%value_to_be_resolved%% | %default_title_suffix%' 

Leider, während params gelöst werden, habe ich seit Dienstleistungen nicht entdeckt. Die einzige Möglichkeit, diesen Ansatz zu umgehen, würde darin bestehen, den Dienstcontainer direkt in den Listener zu stecken und nach dem verpönten Dienst zu fragen.

Gibt es bessere Alternativen? Angesichts der Tatsache, dass ich wirklich Schwierigkeiten hatte, über das Auflösen von Diensten innerhalb von Routen herauszufinden, ist dieser ganze Ansatz etwas, das vermieden werden sollte?

+1

Ich habe noch nie 'defaults' auf diese Weise gesehen. Ist es irgendwo dokumentiert? – martin

+1

Bei Kernel-Listenern wird das Injizieren des Containers als akzeptabel betrachtet. Zumindest mein ich. – Cerad

+0

@Martin Nicht dokumentiert irgendwo, nur meine Naivität erwartet, dass es funktioniert, gegebene Parameter sind gelöst (@see https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Routing/Router. php # L87). Ich hätte auch 'Optionen' dafür verwenden können, aber es gilt das gleiche Problem. –

Antwort

0

Hier ist die Lösung, die ich am Ende mit:

Strecke

example_route: 
    path:  /blah/blah 
    defaults: 
     _controller: MyBundle:MyController:index 
     meta: 
      title: 
       resolver: '@example_title_resolver' 
       value: 'Example | %%value_to_be_resolved%% | %default_title_suffix%' 

Listener 1 - Service-Resolver. Wird direkt nach dem RouterListener mit einer Priorität von 33 oder höher aufgerufen. Zu diesem Zeitpunkt wurden die Routenparameter auf die Anfrage angewendet (@see https://github.com/symfony/http-kernel/blob/master/EventListener/RouterListener.php#L97).

Der mit dem Ereignis kernel.request verbundene Listener hat die Anfrageparameter überprüft und alle Dienste (Zeichenfolgenwerte mit dem Präfix @) für den Service-Container, der in den Listener injiziert wurde, aufgelöst.

Listener 2 - Metadaten-Listener. An diesem Punkt wurde bereits alles auf der Route/Anfrage in Dienste aufgelöst. Dies entkoppelt Bedenken und ermöglicht es weiteren unabhängigen Hörern, von der Fähigkeit zu profitieren, mit Diensten zu kommunizieren, die direkt auf der Anfrage verfügbar sind.

In diesem Beispiel sucht der Metadaten-Listener nach spezifischen Parametern (aufgelöste Services) für die Anforderung. Diese Objekte würden beispielsweise zum Auflösen von Metadatenwerten verwendet. Ein gemeinsamer Mechanismus wäre dann erforderlich, um diese Daten für die Ansicht verfügbar zu machen.

Resolver-Klassen Verantwortlich für die Umwandlung einer gegebenen Template-Zeichenfolge in den endgültigen Wert. Wird vom obigen Metadaten-Listener aufgerufen.

Vorteile

  • betrifft Trennt, Controller mehr wiederverwendbar zu machen.
  • Flexibel, wodurch leichte Resolver-Klassen entwickelt/verworfen werden können.
  • Im konkreten Fall von Metadaten, bietet eine gute Möglichkeit der Zukunftssicherung, wenn einige Routen unvermeidlich neue Arten von Metadaten hinzufügen benötigen. Dies wäre nur ein neuer Resolver und eine kleine Erweiterung der Route (n).

Nachteile

  • Unerwartete Magie zu einem unbekannten Auge.
  • Service-Auflösungswerte von der Anfrage könnten ein Sicherheitsproblem sein, wenn sie nicht richtig behandelt werden.

Ich werde mit diesem für jetzt rollen, wie die Vorteile ansprechend sind. Ich werde einchecken, wenn die Lösung nicht mehr passt.

Verwandte Themen