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

[su_spoiler open=”yes” icon=”” class=”my-spoiler note” title=””]

Определение контроллера как сервиса требует немного больше работы. Главное преимущество в том что сущность контроллера или любого сервиса переданно контроллеру может быть изменено посредством настройки контейнера сервосов. Это особенно полезно когда разрабатывается open-sourse бандл или любой бандл который будет использоваться многократно в других проектах.

Вторым преимужеством это то что ваши контроллеры будут в “песочнице”. Смотря на агрументы конструктора, легко увидеть какого типа они могут быть, а какого нет. И т.к. каждая зависимость должна быть введена вручную, это становится более очевидным ( например если у вам множество агрументов для конструктора ), если ваш контролле большой, и должен быть разделен на много маленьких.

И так, даже если вы не собираетесь определять ваши контроллеры как сервисы, это вероятно будет полезно для вам посмотреть на open-source бандлы в Symfony2. Это важно понимать плюсы и минусы обоих подходов.

[/su_spoiler]

Определение Контроллера как Сервиса

Контроллер может быть определен как сервис как и любой другой класс. Например, если у вас есть следующий контроллер:

Тперь вы можете определить его как сервис:

Ссылаемся на сервис

Чтобы ссылаться на контроллер, который определен как сервис, используется одиночное двоеточие (:). Например, следующий метод indexAction() из сервиса с id acme.hello.controller:

[su_spoiler open=”yes” icon=”” class=”my-spoiler note” title=””]

Вы не можете опустить суффикс Action, когда используете этот синтаксис.

[/su_spoiler]

Вы также можете задать маршрут для сервиса использую туже аннотацию, где определяется значение для _controller:

[su_spoiler open=”yes” icon=”” class=”my-spoiler tip” title=””]

Вы также можете использовать аннотацию для настройки маршрутов используя контроллеры определенные как сервисы. Смотри FrameworkExtraBundle для более детальной инфы.

[/su_spoiler]

Альтернативные для Базовых Методов Контроллера

Если вы используете контроллер, определенный как сервис, скорее всего он не расширяет базовый Controller. Вместо того чтобы полагаться на его методы, вы бедете непосредсвенно работать с сервисами, которые вам нужны. К счастью, это обычно просто и base Controller class source code это отличный источник как реализовать большинство обычных задача.
Например, если вы хотите передать шаблон вместо создание Response объекта напрямую, тогда ваш код будет выглядеть примерно так, если вы расширите базовый контроллер:

Если вы взглянете на исходный код для функции render в base Controller class, вы увидите что этот метод точно также используется для передачи шаблонов сервисам:

В контроллере, который определен как сервис, вы можете вместо вставки службы шаблонов использовать напрямую:

Определение сервиса также нуждается в модификации, чтобы указать аргумент конструктору:

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

[su_spoiler open=”yes” icon=”” class=”my-spoiler note” title=””]

Это не значит что вы не можете расширять ваши контроллеры использую ваш собственные базовый класс. The move away from the standard base controller is because its helper methods rely on having the container available which is not the case for controllers that are defined as services. Это может быть хорошей идеей выделить общий код в сервис, вместо того чтобы вставлять в место базового контроллера, который вы расширяете. Оба подходы правильные, все зависит от того как вы хотите организовать ваш код.

[/su_spoiler]