Konstantin
https://blog.jetbrains.com/blog/2022/03/11/jetbrains-statement-on-ukraine/
Юра
Ничего скоро напишут свою tsaride
Юра
Дабы не залазить в политику предлагаю остановиться
A
Так Роскомнадзор "легализировал" пиратское по) сказали, ломайте, пользуйтесь, преследовать не будем)
A
Если симфа не модетн найти сервис
даже если сервис не используется на текущей странице?
A
у меня произошел взрыв мозга)
A
например, у меня есть контроллер, в экшене которого такие аргументы: RedisInterface $master_redis а сам $master_redis автоварит свои конфигы подключения. если я не вызову экшен контроллера, как симфони узнает, есть ли у меня аргумент $master_redis
Konstantin
скорее всего юзать напрямую редис в контроллере моветон. это слишком низкий уровень - в контроллере работать с хранилищем
Konstantin
там должно быть что-то более абстрактное, чем инстанс подключения к базе
Konstantin
тк на контроллер, как минимум, сильно сложнее написать тест. и лучше работу с подключением к базе инкапсулировать таки в сервис
Konstantin
но это к делу не относится, конечно
A
ну я же пример привел) речь про автовайринг, и про ваш комментарий про то, что симфони выбросит ошибку
Nikolay
ну я же пример привел) речь про автовайринг, и про ваш комментарий про то, что симфони выбросит ошибку
Проходит по всем зависимостям, сопоставляет, создаёт файлы контейнера. Это если упрощённо
A
понял, спасибо
Юра
На самом деле аргументы контроллера резолвятсч в рантайме
Юра
Так что может я не прав и не будет ошибки )
Юра
Пока не обратишься к методу контроллера
Юра
Надо пробовать
Юра
Там оно через аргумент резолвер работает который не только сервисы подставляет в метод контроллера
Юра
Я тоже не.особо люб магию
Юра
Но на практике это удобно и редко когда конкретно с этим бывают проблемы
Юра
Раньше было как ты говоришь и все сервисы описывались явно
Юра
Это пипец неудобно
Nikolay
Раньше было как ты говоришь и все сервисы описывались явно
Это без автовайринга, pimple так работал раньше
Юра
Автоаварийнг вроде с третьей версии симфы?
Nikolay
A
всем привет! у меня такой вопрос: есть сервис, у которого есть два разных метода. одному методу нужны одни зависимости, другому другие. Каждая из зависимостей достаточно тяжелые. На текущий момент эти зависимости внедряются через конструктор. как сделать, чтобы при использовании одного метода, не нужно было в объект внедрять зависимости необходимые другому методу? Один из вариантов - разделить на несколько классов. Но в моем случае не совсем подходит, т.е.это единая зона ответственности. Второй вариант - через сеттеры. Но не понимаю, как в этом случае автоматически будут автовайриться зависимости через нужные сеттеры.
Konstantin
третий вариант - не делать зависимости тяжелыми
Konstantin
не должна инициализация класса (вызов конструктора) быть тяжелой
Konstantin
четвертый вариант: если таки никак без этого и вы точно себе отдаете отчет в осуществляемых действиях (а не "так получилось"), то lazy
Иван
ленивки
A
не должна инициализация класса (вызов конструктора) быть тяжелой
почему? любой сервис сам по себе может быть тяжелый) например какой-то коннекшен куда-то.. разве он не имеет право быть зависимостью ?)
Konstantin
коннекшн надо поднимать при первом использовании, а не при инициализации дерева зависимостей. иначе каждый запуск консольной команды, каждый запуск веб-ядра будет, извините, ставить раком все приложение. вам, наверное, и не нужен был этот коннекшн здесь и сейчас, но за кривое проектирование придется платить при каждом поднятии контекста, это очень больно
Konstantin
единственный нормальный путь - переписать нормально сервисы, чтобы не было такой проблемы
Konstantin
если никак - то костыли, первым в их списке будет лейзи
Konstantin
я для примера) то что могут быть сервисы медленными, и которые могут быть зависимостью.
вообще, инъекция через сеттеры вас не избавит от этой проблемы, кстати. контейнер не знает, что "перед тем как дернут публичный метод doFoo() надо инжектнуть зависимость ххх через сеттер". и контейнер будет точно так же поднимать все зависимости при запуске
A
А что мешает инжектить необходимые зависимости для каждого из методов прямо в них, а коммоновские в конструктор?
в целом как вариант, в клиентском коде получать их через автовайр, и в метод вручну передавать.
Konstantin
поэтому с точки зрения производительности в этом случае разницы между конструктором и сеттером нет. поэтому нет смысла выбирать антипаттерн
Konstantin
в целом как вариант, в клиентском коде получать их через автовайр, и в метод вручну передавать.
это нарушение паттерна ДИ, не должен клиентский код ничего знать о зависимостях конкретного сервиса, вы сейчас в обратную сторону пытаетесь вывернуть "инверсию"
A
вот, я про это и хотел понять
значит сеттеры не совсем подходят(
Ivan
Кто-нибудь пишет нагружённые API на symfony? Не слишком ли он тяжеловесный под это дело?
Konstantin
сеттеры никогда не подходят, обходите их стороной кроме крайних случаев (абстрактные сервисы и общие зависимости, прокидываемые в наследников)
Ivan
Речь про некий аналог rest api
A
нет, совсем нет
хорошо, спасибо, а по ленивой загрузке, как имелось ввиду?
Konstantin
все равно на IO уходит больше времени, приложение сжирает ничтожно мало (с современными фичами вроде jit/opcache/preloading etc)
Ivan
Я понял, спасибо!
Konstantin
хорошо, спасибо, а по ленивой загрузке, как имелось ввиду?
есть ключевое слово lazy у сервис-дефинишнов, оно за вас создает лейзи-прокси вокруг вашего сервиса
Konstantin
выглядит это довольно уродливо, но в запущенных случаях помогает. но я бы советовать ленивость делать таки на уровне своего кода. то есть "поднимать тяжелый коннект" не при запуске, а при первом запросе
A
я знаю как костылём сделать ленивую загрузку. тяжелые зависимости обернуть в еще один класс, который будет возвращать callable. а потом каждый метод пытается вызвать callable и получить объект-зависимость
Konstantin
public function query() { if (!$this->connected) { $this->connect(); } // do the work }
Konstantin
но это стоит каких-то ресурсов, слегка по мне усложняет дебаг и вообще выглядит как заметание реальных проблем под ковёр
A
согласен, понял, спасибо! буду разбираться с тем, как сделать конструкторы легковесными)
Konstantin
вон весь необходимый код выше 🙂
Konstantin
скажете себе потом спасибо - когда тесты не будут по полчаса запускаться, когда любые консольные команды не будут тормозить по полминуты перед запуском, когда не будет странных ошибок, не связанных с запускаемым кодом
Кирилл
private $is_main = true нужно
кстати, а не лучше ли это выносить в конструктор?
Иван
кстати, а не лучше ли это выносить в конструктор?
Зачем? если оно не устанавливается из конструктора, то не надо
A
Подскажите, а насколько сложно внедрить di+autowiring, конфигурируемый через yaml на самописный проект, где используется сторонний роутер.
Konstantin
внедрить не сложно, сделать инъекцию сервисов в аргументы - сложно
A
внедрить не сложно, сделать инъекцию сервисов в аргументы - сложно
а инъекцию сервисов, имеете ввиду, чтобы конфигурировались через yaml ?
Konstantin
нет, в методы контроллеров
Дмитрий
нет, в методы контроллеров
может там инъекция через конструктор
A
а то, что выше написали, если во вронт контроллере, из di-контейнера дернуть контроллер, то он атоматом не разрешит зависимости? (как написали выше)
A
инъекция нужна как через конструктор, так и через методы
A
я так понимаю, это только через рифлексию надо?
A
чтобы в методы прокидывать зависимости
Дмитрий
кстати если проект самопис то почему симфони а не PHP-DI? он кмк попроще будет
A
имеете ввиду от league?
Дмитрий
https://php-di.org/
Дмитрий
и кстати какой роутер?