есть консольная команда. В ней мне нужны репозиторий и http-клиент. Эти зависимости я хотел бы внедрить через конструктор (да или хоть через сеттер, не суть). И есть ещё конфигурация приложения. Это глобальная зависимость, внедрение которой не кажется верным ни через конструктор, ни через сеттер, потому что она не относится к этой консольной команде и в идеале я хотел бы иметь к ней доступ отовсюду. Но и пробрасывать контейнер в команду не кажется верным, согласно документации и здравому смыслу, в приложении должно быть как можно меньше точек зависимостей от контейнера. Очень долго думаю, как этот вопрос решить правильно. Кажется логичной идея использовать на всех классах, где нужен конфиг, сеттер, чтобы установить конфиг. Но тогда я сталкиваюсь с проблемой DRY (везде имплементирую тот же интерфейс или наследую везде тот же базовый класс, или подключаю трейт). Получше пока ничего не придумал. Как вы решаете этот вопрос в своих проектах?
консольная команда - это инфраструктурный уровень. там доменного кода быть не должно.
Посмотри в симфе класс контроллера как сделан, и все поймешь )
Да я смотрел, сам даже повторял. Доступ к контейнеру из контроллера есть, потому что он реализует ContainerAwareInterface. Так вот, это плохая идея, везде давать юзать контейнер.
Что именно "нет"?
Ты инъектишь Psr\Container\ContainerInterface;
https://github.com/symfony/symfony/blob/5.x/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php#L67
Так ты зависишь от интерфейса, абстракции, тем более psr
Ну и что. В любом случае, чем меньше ты завязан на взаимодействие с контейнером, тем твой код чище. О чём и написано в доке.
Где написано? Если ты сам контейнер передаешь, то да, если абстракцию, то норм
https://symfony.com/doc/current/components/dependency_injection.html#avoiding-your-code-becoming-dependent-on-the-container
Это говорится о public сервисах, видимо. Там да, не понятно что ты откуда достаешь. А здесь ты явно прописываешь сервисы.
Конфиг нужен примерно нигде. Любой класс конфигурируется в контейнере, и инжектится тот, который укажешь. Если надо 2 разных варианта одного класса - делаешь в контейнере алиасы с разными параметрами. И инжектишь какой куда надо. Вот и вся магия. Если юзаешь уии, то тут помочь нечем, контейнер очень и очень говенный и не умеет почти ничего. Симфонивский в этом плане намного мощнее и дает возможность реализовать почти любые хотелки.
Нет, вообще пока без фреймворка. Пробую на чистом пхп с подключением любого модуля, который придётся по вкусу. Кажется, так и буду делать.
Обсуждают сегодня