Обновить

Почему не следует напрямую обращаться к глобальному контейнеру в 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

Windows 11 принудительно включит защиту ядра. Убьет ли это fps

Microsoft объявила, что с октября начнет включать целостность памяти на подходящих компьютерах самостоятельно, не спрашивая пользователя. Первым обновлением с этим изменением станет ежемесячный набор исправлений 13 октября. Сама по себе эта штука довольно полезная, и спорить с этим трудно, но у нее есть побочный эффект. Про него говорят нечасто, но геймеры знают о нем уже несколько лет. Собственно, из-за особенностей этой функции многие уже давно сняли эту галку в настройках.

Windows 11 принудительно включит защиту ядра. Убьет ли это fps

Публикации