register($container); } // ── Module registrars (run after all Core registrars) ──────────────── // Module registrars MUST NOT overwrite existing container keys. // The ModuleRegistry is stored in the container for downstream access. $modulesConfig = is_file(__DIR__ . '/../../config/modules.php') ? (array) require __DIR__ . '/../../config/modules.php' : []; $enabledModules = ModuleRegistry::resolveEnabledModules($modulesConfig); $modulesDir = dirname(__DIR__, 2) . '/modules'; $moduleRegistry = ModuleRegistry::boot($modulesDir, $enabledModules); $container->set(ModuleRegistry::class, static fn (): ModuleRegistry => $moduleRegistry); $container->set(ModuleEventDispatcher::class, static fn () => new ModuleEventDispatcher( $moduleRegistry->getEventListeners(), $container )); // Disallow overriding existing core bindings from module registrars. $container->protectExistingBindings(); foreach ($moduleRegistry->getContainerRegistrars() as $registrarClass) { if (!class_exists($registrarClass)) { throw new RuntimeException("Module container registrar class not found: {$registrarClass}"); } $registrarInstance = new $registrarClass(); if (!$registrarInstance instanceof ContainerRegistrar) { throw new RuntimeException( "Module container registrar '{$registrarClass}' must implement " . ContainerRegistrar::class ); } $registrarInstance->register($container); } return $container;