Я также задал этот вопрос вчера, но этот код содержит код.
Мое приложение имеет несколько модулей и 2 типа учетных записей пользователей. Некоторые модули always
загружаются, которые присутствуют в application.config.php
некоторые из них являются conditional
то есть некоторые загружаются для type A
пользователя type A
а некоторые для пользовательского type B
Пройдя через документацию и вопросы о переполнении стека, я понимаю некоторые функции ModuleManager и начал реализовывать логику, которая, хотя я могу работать.
Некоторые из того, как я выяснил способ загрузки модулей, которых нет в application.config.php
[SUCCESS], но их конфигурация не работает [ВЫПУСК], т.е. если в методе onBootstrap
я получаю сервис ModuleManager
и getLoadedModules()
I получить список всех модулей, правильно загруженных. Впоследствии, если я попытаюсь получить некоторую услугу из этого динамически загружаемого модуля, он выдает исключение.
Zend \ ServiceManager \ ServiceManager :: get не удалось получить или создать экземпляр для jobs_mapper
Имейте в виду, что фабрики и все остальное отлично, потому что, если я загружаю модуль из application.config.php, он отлично работает
Аналогично, когда я пытаюсь получить доступ к любому маршруту из динамически загружаемого модуля, он выдает 404 Not Found
который дал понять, что конфигурация модуля module.config.php этих модулей не загружается, даже если модуль загружен ModuleManager.
В Module.php моего модуля приложения я реализовал InitProviderInterface
и добавил метод init(ModuleManager $moduleManager)
где я улавливаю loadModules.post event и загружает модули moduleManager loadModules.post
public function init(\Zend\ModuleManager\ModuleManagerInterface $moduleManager) { $eventManager = $moduleManager->getEventManager(); $eventManager->attach(\Zend\ModuleManager\ModuleEvent::EVENT_LOAD_MODULES_POST, [$this, 'onLoadModulesPost']); }
Затем в том же классе я рассмотрю метод onLoadModulesPost
и начну загружать мои динамические модули
public function onLoadModulesPost(\Zend\ModuleManager\ModuleEvent $event) { /* @var $serviceManager \Zend\ServiceManager\ServiceManager */ $serviceManager = $event->getParam('ServiceManager'); $configListener = $event->getConfigListener(); $authentication = $serviceManager->get('zfcuser_auth_service'); if ($authentication->getIdentity()) { $moduleManager = $event->getTarget(); ... ... $loadedModules = $moduleManager->getModules(); $configListener = $event->getConfigListener(); $configuration = $configListener->getMergedConfig(false); $modules = $modulesMapper->findAll(['is_agency' => 1, 'is_active' => 1]); foreach ($modules as $module) { if (!array_key_exists($module['module_name'], $loadedModules)) { $loadedModule = $moduleManager->loadModule($module['module_name']); //Add modules to the modules array from ModuleManager.php $loadedModules[] = $module['module_name']; //Get the loaded module $module = $moduleManager->getModule($module['module_name']); //If module is loaded succesfully, merge the configs if (($loadedModule instanceof ConfigProviderInterface) || (is_callable([$loadedModule, 'getConfig']))) { $moduleConfig = $module->getConfig(); $configuration = ArrayUtils::merge($configuration, $moduleConfig); } } } $moduleManager->setModules($loadedModules); $configListener->setMergedConfig($configuration); $event->setConfigListener($configListener); } }
Я думаю, что есть некоторая фундаментальная ошибка в том, что вы пытаетесь сделать здесь: вы пытаетесь загрузить модули на основе объединенной конфигурации и, следовательно, создаете циклическую зависимость между модулями и объединенной конфигурацией.
Я бы советовал против этого.
Вместо этого, если у вас есть логика, которая определяет, какая часть приложения должна быть загружена, поместите ее в config/application.config.php
, который отвечает за получение списка модулей.
На этом этапе, однако, слишком рано зависеть от какой-либо службы, поскольку определение услуги зависит также от объединенной конфигурации.
Еще одна вещь, которую нужно прояснить, заключается в том, что вы пытаетесь принять эти решения в зависимости от того, соответствует ли аутентифицированный пользователь (информация запроса, а не информация об окружающей среде) определенным критериям, а затем модифицирует все приложение на основе этого.
Не делайте этого: вместо этого переместите решение в компонент, который должен быть включен / отключен условно, поставив перед ним охрану.
То, что вы просите, может быть сделано, но это не значит, что вы должны.
Предложить подходящее решение, не зная сложность приложения, которое вы строите, сложно.
Использование охранников, безусловно, поможет развязать ваш код, однако использование его в одиночку не касается масштабируемости и ремонтопригодности, если это вызывает беспокойство?
Я бы предложил использовать аутентификацию на основе токенов. Вместо того, чтобы поддерживать логику проверки в каждом приложении, напишите логику проверки в одном общем месте, чтобы каждый запрос мог использовать эту логику независимо от приложения. Выбор обратного прокси-сервера (Nginx) для поддержки логики проверки (с помощью Lua) дает вам гибкость в разработке вашего приложения на любом языке.
Более того, проверка учетных данных на уровне балансировки нагрузки существенно устраняет необходимость в состоянии сеанса, вы можете иметь много отдельных серверов, работающих на нескольких платформах и доменах, повторно используя один и тот же токен для аутентификации пользователя.
Идентификация пользователя, тип учетной записи и загрузка разных модулей становятся тривиальной задачей. Просто передавая информацию о токенах через переменную окружения, ее можно прочитать в файле config/application.config.php
, не требуя предварительного доступа к базе данных, кешу или другим службам.