2016-10-24 3 views
2

Мне нужно реализовать различные атрибуты метаданных для каждого маршрута, и одна из моих идей - применить атрибуты непосредственно на каждом маршруте, чтобы использовать внешний прослушиватель метаданных.Symfony: разрешить сервис по маршруту

Например, слушатель будет использовать службу (@example_title_resolver), определенную на указанном ниже маршруте, для разрешения в какой-либо форме заголовка страницы.

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%' 

К сожалению, в то время как параметры решаются, я с тех пор обнаружил, что службы не работают. Единственный способ, связанный с этим подходом прямо сейчас, заключался бы в том, чтобы инжектировать контейнер службы непосредственно в слушатель и запрашивать службу, на которую нахмурились.

Есть ли лучшие альтернативы? Учитывая, что я действительно изо всех сил пытался узнать о разрешении услуг изнутри маршрутов, есть ли весь этот подход, чего следует избегать?

+1

Я никогда не видел использование 'defaults' таким образом. Документировано ли это где угодно? – martin

+1

В случае слушателей ядра инъекция контейнера считается приемлемой. По крайней мере, я. – Cerad

+0

@Martin Не документировано нигде, только моя наивность ожидает его работы, заданные параметры разрешены (@see https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Routing/Router. PHP # L87). Я мог бы использовать «опции» для этого, но такая же проблема. –

ответ

0

Вот решение, которое я закончил с:

Маршрут

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%' 

Слушатель 1 - Служба распознавателя. Вызывается сразу после RouterListener с приоритетом 33 или выше, в этот момент параметры маршрута применяются к запросу (@see https://github.com/symfony/http-kernel/blob/master/EventListener/RouterListener.php#L97).

Слушатель, прикрепленный к событию kernel.request, проверил параметры запроса и разрешил любые сервисы (строковые значения с префиксом @) против контейнера службы, введенного в слушатель.

Слушатель 2 - прослушиватель метаданных. На этом этапе все на маршруте/запросе уже разрешено в сервисы. Это устраняет проблемы и позволяет дальнейшим несвязанным слушателям извлекать выгоду из возможности разговаривать с услугами, доступными непосредственно по запросу.

В этом примере прослушиватель метаданных будет искать конкретные параметры (разрешенные службы) в запросе. Эти объекты будут использоваться, например, для разрешения значений метаданных. Тогда потребуется общий механизм, чтобы сделать эти данные доступными для представления.

Классы резольвера Ответственный за превращение данной строки шаблона в конечное значение. Вызывается получателем метаданных выше.

Преимущества

  • Разделяет опасения, что делает контроллеры более универсальными.
  • Гибкий, позволяющий разрабатывать/отбрасывать классы легкого класса резольвера.
  • В конкретном случае метаданных обеспечивает хороший способ будущей проверки, когда неизбежно для некоторых маршрутов потребуются новые типы добавления метаданных. Это будет просто новый резольвер и небольшое дополнение к маршрутам.

Недостатков

  • Неожиданная магия незнакомого глаз.
  • Служба, разрешающая значения из запроса, может быть проблемой безопасности, если ее не обрабатывать должным образом.

Я собираюсь покататься с этим, поскольку преимущества привлекательны. Я проверю, когда решение больше не подходит.

Смежные вопросы