Комментарии 15
А зачем собственно нам нужно делать такие изменения? Есть ли какой нибудь пример из реальной жизни где такой вариант будет реально полезен? У вас действительно есть контроллер который используется в 2-х фреймворках одновременно?
+1
В третьей части автор поясняет свою точку зрения на этот вопрос, скоро я эту часть допереведу, сможете там прочитать. А вообще, обобщая позицию автора, суть тут в том, что разработчик сам по себе начинает лучше замечать зависимости, и ему больше не кажутся «магией» аннотации и конвертеры параметров. Ну и плюс, контроллер-как-сервис очень проще для восприятия, чем ContainerAware-контроллер — все зависимости сразу видно; сразу, например, понятно, нужен ли контроллеру доступ к БД, и если нужен, то к каким репозиториям, и так далее.
+2
Вообще в свое время ContainerAware контроллеры приходилось делать, это только с Symfony 2.3 DiC поддерживает ленивую инициализацию зависимостей (оборачивает их в прокси-объекты). Раньше же при инициализации контроллера инициировались и все все все сервисы, которые мы инджектили. Что бы этого избежать, приходилось инджектить контейнер целиком.
+1
У меня был случай, когда в рамках рефакторинга проекта и его последующего переноса на другой фреймворк, пришлось вносить отдельный слой отделяющий компоненты фреймворка от приложения. В целом обычно это хорошая практика. Например отвязать контроллеры от Doctrine (инджектить отдельно репозитории и завязывать их на свои интерфейсы, не используя снаружи функционал Doctrine), что позволит быстро и безболезненно сменить хранилище данных. В последней части этой серии статей автор даже сам говорит, что отвязывать контроллеры и от HttpKernel это перебор, хотя раз уж начали то так будет правильно.
0
На самом деле, основные плюсы кроются не в том, что контроллер можно реюзать, а скорее, наоборот, тонкий клиент и связывание дает кунштюки:
— Можно заменить сервис, реализующий ту или иную плюшку (например, подменив EntityManager доктрины часть самых тяжелых методов перепишется на максимально быстрый нейтив)
— С инъекциями проще потом поверх нужных методов подцепить что-то еще. Например, логгер.
— Замена некоторых зависимостей полностью — не такой уж частый, но важный кейс в разработке хоть сколько-то дольше месяца,
— Наконец, позволяет тестировать сервисы модульно, в своих контекстах, так что контроллер, который тянет за собой все окружение, тестировать или не надо, или просто, или достаточно пары функциональных стандартных тестов.
— Можно заменить сервис, реализующий ту или иную плюшку (например, подменив EntityManager доктрины часть самых тяжелых методов перепишется на максимально быстрый нейтив)
— С инъекциями проще потом поверх нужных методов подцепить что-то еще. Например, логгер.
— Замена некоторых зависимостей полностью — не такой уж частый, но важный кейс в разработке хоть сколько-то дольше месяца,
— Наконец, позволяет тестировать сервисы модульно, в своих контекстах, так что контроллер, который тянет за собой все окружение, тестировать или не надо, или просто, или достаточно пары функциональных стандартных тестов.
0
Спасибо все ответы весьма неплохие. Возможно тогда стоит немного изменить название темы например: «Как уменьшить связность контроллера с фреймворком». Все ответы говорят о том что основная цель это не использование нескольких фреймворков с одним кодом, а именно уменьшение связности классов контроллеров. И в таком варианте это действительно имеет смысл. Правда я думаю что в таком случае подходить стоит без особого фанатизма например явная инъекция зависимостей это однозначно хорошо а вот отказываться от сахара аннотаций думаю нет большого смысла.
0
Ну, мопед не мой, а по футеру так и текст переводной.
Про аннотации — мне самому они очень нравятся, особенно в роли описания кеша/темплейтов/и т.п., но порой действительно вынос роутингов в дерево yaml дает большую гибкость, особенно в больших проектах. По крайней мере, ищется нужный даже в большой команде легко, роуты видно в одном месте (и на одном экране, что важно),
и самое главное — для Symfony — проще делать иерархию роутинга (чтобы все роутинги /api/ были описаны в другом файле, при этом префикс задается в одном месте).
Хотя, когда писали самодокументируемый REST-сервис с помощью NelmioApiDocBundle, многое было на аннотациях и было очень вкусно и красиво, даже описание парамтетров, передаваемых в query, и принимаемых в POST сущностей.
Про аннотации — мне самому они очень нравятся, особенно в роли описания кеша/темплейтов/и т.п., но порой действительно вынос роутингов в дерево yaml дает большую гибкость, особенно в больших проектах. По крайней мере, ищется нужный даже в большой команде легко, роуты видно в одном месте (и на одном экране, что важно),
и самое главное — для Symfony — проще делать иерархию роутинга (чтобы все роутинги /api/ были описаны в другом файле, при этом префикс задается в одном месте).
Хотя, когда писали самодокументируемый REST-сервис с помощью NelmioApiDocBundle, многое было на аннотациях и было очень вкусно и красиво, даже описание парамтетров, передаваемых в query, и принимаемых в POST сущностей.
0
роуты видно в одном месте (и на одном экране, что важно)
Вы все еще в ручную глазами в конфигах ищите соответствия роутов экшенам?
php app/console router:debug
в связке с grep будте в любом случаее удобней.В PhpStorm можно просто по названию роута сразу в нужный экшен попасть:
0
Ну, это про поиск и навигацию по аннотированным
Имхо, куда удобнее будет сделать изменения в одном или нескольких
Кстати, это еще один аргумент за конфиги и против аннотаций.
@Route
экшенам. А если вы вдруг, например, захотите во всех экшенах суффикс _list
заменить на _index
, например? Или, например, для всех рутов с суффиксом _new
ограничить методы только POST
'ом?Имхо, куда удобнее будет сделать изменения в одном или нескольких
routing.yml
и получить красивый и аккуратный коммит, по changeset'у которого явно видно, что он касается только роутинга, нежели получить изменения в большинстве, а то и во всех контроллерах.Кстати, это еще один аргумент за конфиги и против аннотаций.
+1
Согласен, но вы описали редкую задачу. Для меня удобство видеть с кодом экшена и его роут, поддерживаемые http-методы, шаблоны и т. д. перевешивает недостатки.
С хранением роутов в одном файл сталкивался в rails. Для больших проектов это выглядит довольно дико.
С хранением роутов в одном файл сталкивался в rails. Для больших проектов это выглядит довольно дико.
0
Но ведь вам никто не мешает разносить роутинг по бандлам! Более того, это даже рекомендуемый путь для Symfony2-приложений. При генерации бандла конфигурация роутинга для него не конкатится к
И что еще важнее, вы вполне можете объявить несколько конфигураций роутинга в рамках одного бандла, либо точно так же инклудить другие конфиги при помощи
Получается, что в пути
app/config/routing.yml
, а инклудится в нем:ck_finder:
resource: "@JonlilCKFinderBundle/Resources/config/routing/routing.yml"
prefix: /cms/ckfinder
И что еще важнее, вы вполне можете объявить несколько конфигураций роутинга в рамках одного бандла, либо точно так же инклудить другие конфиги при помощи
resource
.Получается, что в пути
src/My/AcmeBundle/resources/config
могут быть, например, сразу routing_front.yml
и routing_admin.yml
, импортируемые в app/config/routing
:acme_front:
resource: '@MyAcmeBundle/Resources/config/routing_front.yml'
prefix: /
acme_admin:
resource: '@MyAcmeBundle/Resources/config/routing_admin.yml'
prefix: /admin/
+1
Все что описывается в статье не имеет никакого отношения к небольшим проектам и быстрой разработке. То есть обычно на таких проектах и так не пользуются аннотациями или хотя бы стараются не использовать их. Если уж выбран один формат хранения конфигов — стараются придерживаться именно его. В зависимости от проекта можно перенимать лишь часть практик.
+1
Кстати, вот и допереведенная третья часть.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Как делать независимые от фреймворка контроллеры?