Обновить

Почему не следует напрямую обращаться к глобальному контейнеру в Joomla 5

Что общего у нижеперечисленных методов?

  • Joomla\CMS\Factory::getCache()

  • Joomla\CMS\Factory::getDbo()

  • Joomla\CMS\Factory::getMailer()

  • Joomla\CMS\Application\AdministratorApplication::getRouter()

  • Joomla\CMS\Application\Administrator\ApiApplication::getRouter()

  • Joomla\CMS\Toolbar\Toolbar::getInstance()

Они объявлены устаревшими с Joomla 4.x и вместо них предлагается использовать Joomla\CMS\Factory::getContainer()->get('Соответствующий_интерфейс').

Например, вместо Joomla\CMS\Factory::getDbo()Factory::getContainer()->get(DatabaseInterface::class);

Но давайте посмотрим на описание метода Joomla\CMS\Factory::getContainer():

Возвращает глобальный контейнер сервисов, создавая его только в случае отсутствия.

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

Допустимые сценарии использования:

  • Статический метод getInstance(), вызывающий сервис из контейнера (пример: Joomla\CMS\Toolbar\Toolbar::getInstance());

  • Фронт-контроллер приложения, загружающий и исполняющий класс Joomla (пример: файл cli/joomla.php);

  • Получение опциональных зависимостей конструктора во время переходного периода для сохранения обратной совместимости (в этом случае следует добавлять уведомление об устаревании).

Не рекомендуется использовать этот метод как прямую замену статическим вызовам, например заменять Factory::getDbo() на Factory::getContainer()->get(DatabaseInterface::class). Вместо этого код следует рефакторить для использования внедрения зависимостей.

В последнем абзаце видим явное противоречие и рекомендацию использовать зависимости.

Как же внедрять зависимости?

Рассмотрим как это сделано в плагине joomla группы content:

В сервис-провайдере плагина Root/plugins/content/joomla/services/provider.php используются методы setDatabase() и setUserFactory() для установки зависимостей.

$plugin->setDatabase($container->get(DatabaseInterface::class));
$plugin->setUserFactory($container->get(UserFactoryInterface::class));

А в классе расширения плагина plugins/content/joomla/src/Extension/Joomla.php используются методы getDatabase() и getUserFactory(). Аналогично в компонентах.

Мой пример использования:

В компоненте обновления цен для JoomShopping, в моделях работающих с товарами я заменил драйвер базы данных на свой, соединяющийся с базой другого сайта. Код самих моделей при этом изменять не потребовалось.

Выводы:

  • Сервис-провайдер расширения — единая точка установки зависимостей для своего расширения.

  • Событие onAfterExtensionBoot - точка для замены зависимости в любом расширении.

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

Материалы по теме:

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Я перестал пользоваться самыми умными ИИ‑моделями. Программировать стало быстрее и дешевле

В отпуске есть время подумать и исследовать. Я натолкнулся на несколько вещей и открытий для себя. Оказалось, что мне как программисту перестали быть нужны самые умные и дорогие ИИ‑модели. Оказывается, есть такой параметр «Cost per Task», и по этому параметру на первое место вырвалась модель GPT-5.6 Luna (max).

При этом, если вы пользуетесь Codex, она самая тупая в списке моделей. Artificial Analysis Intelligence Index у нее всего 38. Для сравнения, у самой умной GPT-6 Astra (max) этот индекс равен 53. В итоге цена выполненной Luna задачи составляет $0.18 против $3.26 у Astra. Разница почти в 20 раз.

Как я понимаю, бенчмарк «Cost per Task» высчитывается так: когда ставится нормальная, грамотно описанная задача, замеряется, сколько токенов было потрачено на ее выполнение. То есть не в формате «из ХЗ сделаю ТЗ», а в формате, когда в хорошо заданном вопросе уже содержится половина ответа.

Я сначала не поверил, что так и есть, и стал работать, используя самую тупую модель Luna в линейке. И знаете, какие меня ожидали результаты?

Я перестал пользоваться самыми умными ИИ‑моделями. Программировать стало быстрее и дешевле

Публикации