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); $coreKeys = []; // snapshot keys before module registrars // We use reflection-free approach: track what the container had before modules 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;