diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 1f2aee62ec05a1cb0981368b6bc89e728a36511d..c3e889c5b35865a95f8c1bf9fca78e9e81d67503 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -1,10 +1,5 @@
 parameters:
 	ignoreErrors:
-		-
-			message: "#^Call to an undefined method TYPO3\\\\CMS\\\\Core\\\\Context\\\\AspectInterface\\:\\:isPreview\\(\\)\\.$#"
-			count: 1
-			path: ../../typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php
-
 		-
 			message: "#^Call to an undefined method TYPO3\\\\CMS\\\\Core\\\\Resource\\\\FolderInterface\\:\\:getCombinedIdentifier\\(\\)\\.$#"
 			count: 1
diff --git a/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php b/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php
index c743eb75001ff0d7f45101e9bb0d045f5dd3520b..6009e39602ecc681661f4f496bb493c43405c014 100644
--- a/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php
+++ b/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php
@@ -22,7 +22,6 @@ use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
 use TYPO3\CMS\Adminpanel\Service\ModuleLoader;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Http\JsonResponse;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Admin Panel Ajax Controller - Route endpoint for ajax actions
@@ -32,16 +31,12 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 class AjaxController
 {
     protected array $adminPanelModuleConfiguration;
-    protected ModuleLoader $moduleLoader;
-    private ConfigurationService $configurationService;
 
-    public function __construct(?ConfigurationService $configurationService = null, ?ModuleLoader $moduleLoader = null)
-    {
-        $this->configurationService = $configurationService
-                                      ??
-                                      GeneralUtility::makeInstance(ConfigurationService::class);
+    public function __construct(
+        private readonly ConfigurationService $configurationService,
+        private readonly ModuleLoader $moduleLoader,
+    ) {
         $this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? [];
-        $this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class);
     }
 
     /**
diff --git a/typo3/sysext/adminpanel/Classes/Controller/MainController.php b/typo3/sysext/adminpanel/Classes/Controller/MainController.php
index bfa0129312db1bf79dfd0644e8691cd2688569aa..a37fe53e5180834b73700f2e5e3a242b6c74a5fa 100644
--- a/typo3/sysext/adminpanel/Classes/Controller/MainController.php
+++ b/typo3/sysext/adminpanel/Classes/Controller/MainController.php
@@ -26,46 +26,35 @@ use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface;
 use TYPO3\CMS\Adminpanel\ModuleApi\RequestEnricherInterface;
 use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
 use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
-use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
 use TYPO3\CMS\Adminpanel\Service\ModuleLoader;
 use TYPO3\CMS\Adminpanel\Utility\ResourceUtility;
 use TYPO3\CMS\Adminpanel\Utility\StateUtility;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Cache\CacheManager;
-use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\View\StandaloneView;
 
 /**
- * Main controller for the admin panel
+ * Main controller for the admin panel.
+ *
+ * Note this is a "shared" / singleton object: Middleware AdminPanelInitiator
+ * instantiates the object and eventually calls initialize(). Later,
+ * AdminPanelRenderer calls render() on the same object.
  *
  * @internal
  */
-class MainController implements SingletonInterface
+class MainController
 {
-    /**
-     * @var array<string, ModuleInterface>
-     */
+    /** @var array<string, ModuleInterface> */
     protected array $modules = [];
-
-    protected ModuleLoader $moduleLoader;
-    protected UriBuilder $uriBuilder;
-    protected ConfigurationService $configurationService;
     protected array $adminPanelModuleConfiguration;
 
     public function __construct(
-        ?ModuleLoader $moduleLoader = null,
-        ?UriBuilder $uriBuilder = null,
-        ?ConfigurationService $configurationService = null
+        private readonly ModuleLoader $moduleLoader,
+        private readonly UriBuilder $uriBuilder,
     ) {
-        $this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class);
-        $this->uriBuilder = $uriBuilder ?? GeneralUtility::makeInstance(UriBuilder::class);
-        $this->configurationService = $configurationService
-                                      ?? GeneralUtility::makeInstance(ConfigurationService::class);
-        $adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? [];
-        $this->adminPanelModuleConfiguration = is_array($adminPanelModuleConfiguration)
-            ? $adminPanelModuleConfiguration : [];
+        $this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? [];
     }
 
     /**
@@ -76,7 +65,6 @@ class MainController implements SingletonInterface
         $this->modules = $this->moduleLoader->validateSortAndInitializeModules(
             $this->adminPanelModuleConfiguration
         );
-
         if (StateUtility::isActivatedForUser()) {
             $request = $this->initializeModules($request, $this->modules);
         }
diff --git a/typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php b/typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php
deleted file mode 100644
index b47b9b5d0092e350102062b07f809136df246098..0000000000000000000000000000000000000000
--- a/typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-namespace TYPO3\CMS\Adminpanel\Exceptions;
-
-/**
- * Exception class for invalid admin panel configuration
- */
-class InvalidConfigurationException extends \RuntimeException
-{
-}
diff --git a/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php b/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php
index 52dc67f905fbc14b887f6dc8b84b3d11981f9294..63406d70e1b74698c26a37c2845498729c95b502 100644
--- a/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php
+++ b/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php
@@ -29,31 +29,14 @@ class DoctrineSqlLogger implements SQLLogger, LoggerAwareInterface
 {
     use LoggerAwareTrait;
 
-    /**
-     * Executed SQL queries.
-     *
-     * @var array
-     */
-    protected $queries = [];
+    /** Executed SQL queries. */
+    protected array $queries = [];
+    /** If Debug Stack is enabled (log queries) or not. */
+    protected bool $enabled = true;
+    protected float $start;
+    protected int $currentQuery = 0;
 
-    /**
-     * If Debug Stack is enabled (log queries) or not.
-     *
-     * @var bool
-     */
-    protected $enabled = true;
-
-    /**
-     * @var float
-     */
-    protected $start;
-
-    /**
-     * @var int
-     */
-    protected $currentQuery = 0;
-
-    public function startQuery($sql, array $params = null, array $types = null)
+    public function startQuery($sql, array $params = null, array $types = null): void
     {
         if ($this->enabled && MemoryUtility::isMemoryConsumptionTooHigh()) {
             $this->enabled = false;
@@ -78,7 +61,7 @@ class DoctrineSqlLogger implements SQLLogger, LoggerAwareInterface
         }
     }
 
-    public function stopQuery()
+    public function stopQuery(): void
     {
         if ($this->enabled) {
             $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start;
diff --git a/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php b/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php
index dc5fe97c07f56586fa5f23a555defb1f3c0c2b6b..4ae09603a55fd9795656ca483011a55bffd873eb 100644
--- a/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php
+++ b/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php
@@ -24,28 +24,24 @@ use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Http\ApplicationType;
 use TYPO3\CMS\Core\Log\LogRecord;
 use TYPO3\CMS\Core\Log\Writer\AbstractWriter;
+use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Log writer that writes the log records into a static public class variable
- * for InMemory processing
+ * for InMemory processing. Note this implements SingletonInterface so multiple
+ * calls to this class can accumulate log records in the same instance.
+ *
+ * @internal
  */
-class InMemoryLogWriter extends AbstractWriter
+final class InMemoryLogWriter extends AbstractWriter implements SingletonInterface
 {
-    /**
-     * @var LogRecord[]
-     */
-    public static $log = [];
-
-    /**
-     * @var bool
-     */
-    private static $memoryLock = false;
+    /** @var LogRecord[] */
+    private array $log = [];
+    private bool $memoryLock = false;
 
     /**
      * Writes the log record
-     *
-     * @param LogRecord $record Log record
      */
     public function writeLog(LogRecord $record): self
     {
@@ -53,7 +49,7 @@ class InMemoryLogWriter extends AbstractWriter
         if (Environment::isCli()
             || !(($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof  ServerRequestInterface)
             || !ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend()
-            || self::$memoryLock === true
+            || $this->memoryLock === true
         ) {
             return $this;
         }
@@ -64,23 +60,31 @@ class InMemoryLogWriter extends AbstractWriter
             return $this;
         }
 
-        self::$log[] = (clone $record)->setMessage($this->interpolate($record->getMessage(), $record->getData()));
+        $this->log[] = (clone $record)->setMessage($this->interpolate($record->getMessage(), $record->getData()));
 
         return $this;
     }
 
+    /**
+     * @return LogRecord[]
+     */
+    public function getLogEntries(): array
+    {
+        return $this->log;
+    }
+
     /**
      * Lock writer and add an info message that there may potentially be more entries.
      */
-    protected function lockWriter(): void
+    private function lockWriter(): void
     {
-        self::$memoryLock = true;
+        $this->memoryLock = true;
         $record = GeneralUtility::makeInstance(
             LogRecord::class,
             'TYPO3.CMS.AdminPanel.Log.InMemoryLogWriter',
             LogLevel::INFO,
             '... Further log entries omitted, memory usage too high.'
         );
-        self::$log[] = $record;
+        $this->log[] = $record;
     }
 }
diff --git a/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php b/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php
index 90863809305f7b583645867d1aa789b1ca79a731..7c9146fe2bfa1f9cd3791db4fef4234e4fde31f3 100644
--- a/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php
+++ b/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php
@@ -33,14 +33,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class SqlLogging implements MiddlewareInterface
 {
-    /**
-     * @var ConnectionPool
-     */
-    protected $connectionPool;
-
-    public function __construct(ConnectionPool $connectionPool)
-    {
-        $this->connectionPool = $connectionPool;
+    public function __construct(
+        private readonly ConnectionPool $connectionPool
+    ) {
     }
 
     /**
diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php
index c2a5015796eaf27cfd3998ffa1eb1194f55718b6..3f62e5482b69f8e3ebba81c64a1d9884fdca7bdc 100644
--- a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php
+++ b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php
@@ -20,7 +20,6 @@ namespace TYPO3\CMS\Adminpanel\ModuleApi;
 use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Abstract base class for Admin Panel Modules containing helper methods and default interface implementations
@@ -28,34 +27,23 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 abstract class AbstractModule implements ModuleInterface, ConfigurableInterface, SubmoduleProviderInterface
 {
-    /**
-     * @var ModuleInterface[]
-     */
-    protected $subModules = [];
-
-    /**
-     * Main Configuration (from UserTSConfig, admPanel)
-     *
-     * @var array
-     */
-    protected $mainConfiguration;
-
-    /**
-     * @var ConfigurationService
-     */
-    protected $configurationService;
+    /** @var ModuleInterface[] */
+    protected array $subModules = [];
+    /** Main Configuration (from UserTSConfig, admPanel) */
+    protected array $mainConfiguration;
+    protected ConfigurationService $configurationService;
 
-    public function __construct()
+    public function injectConfigurationService(ConfigurationService $configurationService): void
     {
-        $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
+        $this->configurationService = $configurationService;
         $this->mainConfiguration = $this->configurationService->getMainConfiguration();
     }
 
     /**
      * Returns true if the module is
-     * -> either enabled via TSConfig admPanel.enable
-     * -> or any setting is overridden
-     * override is a way to use functionality of the admin panel without displaying the admin panel to users
+     * -> either enabled via TSConfig "admPanel.enable"
+     * -> or any setting is overridden.
+     * Override is a way to use functionality of the admin panel without displaying the admin panel to users
      * for example: hidden records or pages can be displayed by default
      */
     public function isEnabled(): bool
@@ -104,7 +92,7 @@ abstract class AbstractModule implements ModuleInterface, ConfigurableInterface,
     }
 
     /**
-     * Returns true if TSConfig admPanel.enable is set for this module (or all modules)
+     * Returns true if TSConfig "admPanel.enable" is set for this module (or all modules)
      */
     protected function isEnabledViaTsConfig(): bool
     {
diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php
index dfa5ab6155278979e0af08cf38c7994fb8578b21..62f4aaf440a092182d681c996cc1f16136b3f74c 100644
--- a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php
+++ b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php
@@ -21,9 +21,9 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Localization\LanguageService;
 
 /**
- * Abstract SubModule - Base class for sub modules in the admin panel
+ * Abstract SubModule - Base class for submodules in the admin panel
  *
- * Extend this class when writing own sub modules
+ * Extend this class when writing own submodules
  */
 abstract class AbstractSubModule implements ModuleInterface, ContentProviderInterface
 {
diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php
index 5ebf56190d666b3fa9c9ad15331a0ffe3a0152d2..365cf5d872014742552a62d1df5b509316f71c4f 100644
--- a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php
+++ b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php
@@ -21,7 +21,7 @@ namespace TYPO3\CMS\Adminpanel\ModuleApi;
  * ModuleData is a simple wrapper object which extends ArrayObject
  * which is used to hold Adminpanel module data
  *
- * It's a separate class to add semantic meaning to its' usage
+ * It's a separate class to add semantic meaning to its usage
  */
 class ModuleData extends \ArrayObject
 {
diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php
index 759b68b52fd89e8a47f1ca912d195f62438448aa..9ec3df6e99d447e7f1b3660790a12f8d2d22e852 100644
--- a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php
+++ b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php
@@ -27,10 +27,7 @@ class ModuleDataStorageCollection extends \SplObjectStorage
         $this->attach($module, $moduleData);
     }
 
-    /**
-     * @param object $object
-     */
-    public function getHash($object): string
+    public function getHash(object $object): string
     {
         if ($object instanceof ModuleInterface) {
             return $object->getIdentifier();
diff --git a/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php b/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php
index a784d7c576863ca2355cd7967fd4cc8793a56502..7ea1f9f441b776459e939df7565fde5c2d08c0d5 100644
--- a/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php
+++ b/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php
@@ -37,12 +37,11 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
 class Log extends AbstractSubModule implements DataProviderInterface, ModuleSettingsProviderInterface, RequestEnricherInterface
 {
     protected int $logLevel;
-    protected ConfigurationService $configurationService;
 
-    public function __construct()
-    {
+    public function __construct(
+        private readonly ConfigurationService $configurationService,
+    ) {
         $this->logLevel = LogLevel::normalizeLevel(\Psr\Log\LogLevel::INFO);
-        $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
     }
 
     public function getIdentifier(): string
@@ -71,10 +70,10 @@ class Log extends AbstractSubModule implements DataProviderInterface, ModuleSett
             ];
         }
 
-        $log = InMemoryLogWriter::$log;
+        $logRecords = GeneralUtility::makeInstance(InMemoryLogWriter::class)->getLogEntries();
 
         $logArray = [];
-        foreach ($log as $logRecord) {
+        foreach ($logRecords as $logRecord) {
             $entry = $logRecord->toArray();
             // store only necessary info
             unset($entry['data']);
diff --git a/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php b/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php
index 132c2c6196b90d8bd9becd6c4c3099e0995f817f..a5a98835d3dc31b027415f69d13d8c0f91aa4ab7 100644
--- a/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php
+++ b/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php
@@ -22,6 +22,7 @@ use TYPO3\CMS\Adminpanel\Log\InMemoryLogWriter;
 use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule;
 use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
 use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\View\StandaloneView;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
@@ -68,8 +69,8 @@ class PageTitle extends AbstractSubModule implements DataProviderInterface
                 'skippedProviders' => [],
             ];
 
-            $log = InMemoryLogWriter::$log;
-            foreach ($log as $logEntry) {
+            $logRecords = GeneralUtility::makeInstance(InMemoryLogWriter::class)->getLogEntries();
+            foreach ($logRecords as $logEntry) {
                 if ($logEntry->getComponent() === self::LOG_COMPONENT) {
                     $logEntryData = $logEntry->getData();
                     if (isset($logEntryData['orderedTitleProviders'])) {
diff --git a/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php b/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php
index bffa30ddaffd8d7ee637e821ad6a77e0f407c3a8..cc6fd3911844a04ce0560c4742f7e5f680a6bb2f 100644
--- a/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php
+++ b/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php
@@ -22,6 +22,7 @@ use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule;
 use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
 use TYPO3\CMS\Core\Log\LogLevel;
 use TYPO3\CMS\Core\Log\LogRecord;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Debug Module of the AdminPanel
@@ -47,7 +48,8 @@ class DebugModule extends AbstractModule implements ShortInfoProviderInterface
 
     public function getShortInfo(): string
     {
-        $errorsAndWarnings = array_filter(InMemoryLogWriter::$log, static function (LogRecord $entry) {
+        $logRecords = GeneralUtility::makeInstance(InMemoryLogWriter::class)->getLogEntries();
+        $errorsAndWarnings = array_filter($logRecords, static function (LogRecord $entry) {
             return LogLevel::normalizeLevel($entry->getLevel()) <= 4;
         });
         return sprintf($this->getLanguageService()->sL(
diff --git a/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php b/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php
index ae03bf02eb30bbe6b872cf21a1671599ef7b928a..b7f8c1f8fb9c1790dde93820e8763a67fdd2957b 100644
--- a/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php
+++ b/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php
@@ -49,7 +49,7 @@ class PreviewModule extends AbstractModule implements RequestEnricherInterface,
      *     showFluidDebug?: bool
      * }
      */
-    protected $config;
+    protected array $config;
 
     public function getIconIdentifier(): string
     {
@@ -198,6 +198,7 @@ class PreviewModule extends AbstractModule implements RequestEnricherInterface,
         }
         $isPreview = $simulateUserGroup || $simTime || $showHiddenPages || $showHiddenRecords || $showScheduledRecords;
         if ($context->hasAspect('frontend.preview')) {
+            /** @var PreviewAspect $existingPreviewAspect */
             $existingPreviewAspect = $context->getAspect('frontend.preview');
             $isPreview = $existingPreviewAspect->isPreview() || $isPreview;
         }
diff --git a/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php b/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php
index 3608c3d2b53cda78c0bcb77890ed78c7d5099556..2abd7b560fa1027b95753eaff1da9a0642699e2c 100644
--- a/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php
+++ b/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php
@@ -36,11 +36,9 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
  */
 class TypoScriptWaterfall extends AbstractSubModule implements RequestEnricherInterface, ModuleSettingsProviderInterface
 {
-    protected ConfigurationService $configurationService;
-
-    public function __construct()
-    {
-        $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
+    public function __construct(
+        private readonly ConfigurationService $configurationService,
+    ) {
     }
 
     public function getIdentifier(): string
diff --git a/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php b/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php
index b36200cc4b54f21fd65a17258ca667469840841d..930aca99ddac1c579c0ca15f105244c4cc520553 100644
--- a/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php
+++ b/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php
@@ -94,13 +94,10 @@ class ConfigurationService implements SingletonInterface
         return $GLOBALS['BE_USER'];
     }
 
-    /**
-     * @param array $configurationToSave
-     */
     protected function triggerOnSubmitActors(
         array $modules,
         ServerRequestInterface $request,
-        $configurationToSave
+        array $configurationToSave
     ): void {
         foreach ($modules as $module) {
             if (
diff --git a/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php b/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php
index 65e03af860e10e1c4f49eaa077755f1f5da08b7d..21829ecd1e628def5a0f3acfc87486fb6ce7dafb 100644
--- a/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php
+++ b/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php
@@ -17,7 +17,6 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Adminpanel\Service;
 
-use TYPO3\CMS\Adminpanel\Exceptions\InvalidConfigurationException;
 use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface;
 use TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface;
 use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
@@ -45,7 +44,7 @@ class ModuleLoader
         }
         foreach ($modules as $identifier => $configuration) {
             if (empty($configuration) || !is_array($configuration)) {
-                throw new InvalidConfigurationException(
+                throw new \RuntimeException(
                     'Missing configuration for module "' . $identifier . '".',
                     1519490105
                 );
@@ -59,7 +58,7 @@ class ModuleLoader
                     true
                 )
             ) {
-                throw new InvalidConfigurationException(
+                throw new \RuntimeException(
                     'The module "' .
                     $identifier .
                     '" defines an invalid module class. Ensure the class exists and implements the "' .
diff --git a/typo3/sysext/adminpanel/Configuration/Services.yaml b/typo3/sysext/adminpanel/Configuration/Services.yaml
index e7f368488d86237d2c5ce00c0d934791095b9145..cd9d118b591c2d06d31af58205eabc3785b300ad 100644
--- a/typo3/sysext/adminpanel/Configuration/Services.yaml
+++ b/typo3/sysext/adminpanel/Configuration/Services.yaml
@@ -12,6 +12,25 @@ services:
     factory: ['@TYPO3\CMS\Core\Cache\CacheManager', 'getCache']
     arguments: ['adminpanel_requestcache']
 
+  TYPO3\CMS\Adminpanel\Controller\AjaxController:
+    public: true
+  TYPO3\CMS\Adminpanel\Controller\MainController:
+    public: true
+
+  TYPO3\CMS\Adminpanel\Modules\CacheModule:
+    public: true
+  TYPO3\CMS\Adminpanel\Modules\DebugModule:
+    public: true
+  TYPO3\CMS\Adminpanel\Modules\InfoModule:
+    public: true
+  TYPO3\CMS\Adminpanel\Modules\PreviewModule:
+    public: true
+  TYPO3\CMS\Adminpanel\Modules\TsDebugModule:
+    public: true
+  TYPO3\CMS\Adminpanel\Modules\Debug\Log:
+    public: true
+  TYPO3\CMS\Adminpanel\Modules\TsDebug\TypoScriptWaterfall:
+    public: true
 
   Psr\EventDispatcher\EventDispatcherInterface:
     alias: TYPO3\CMS\Adminpanel\Service\EventDispatcher
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php
index bba8076625bf6d45a076f5664f4fbcb18eb7dd59..7e5803c450181aff6a683b30881d084b17193e2e 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php
@@ -40,8 +40,6 @@ class MainModuleFixture implements
     /**
      * Identifier for this module,
      * for example "preview" or "cache"
-     *
-     * @return string
      */
     public function getIdentifier(): string
     {
@@ -50,8 +48,6 @@ class MainModuleFixture implements
 
     /**
      * Module label
-     *
-     * @return string
      */
     public function getLabel(): string
     {
@@ -60,8 +56,6 @@ class MainModuleFixture implements
 
     /**
      * Module Icon identifier - needs to be registered in iconRegistry
-     *
-     * @return string
      */
     public function getIconIdentifier(): string
     {
@@ -70,17 +64,12 @@ class MainModuleFixture implements
 
     /**
      * Displayed directly in the bar if module has content
-     *
-     * @return string
      */
     public function getShortInfo(): string
     {
         return 'short info';
     }
 
-    /**
-     * @return string
-     */
     public function getPageSettings(): string
     {
         return 'example settings';
@@ -92,8 +81,6 @@ class MainModuleFixture implements
      * A module may be enabled but not shown
      * -> only the initializeModule() method
      * will be called
-     *
-     * @return bool
      */
     public function isEnabled(): bool
     {
@@ -104,9 +91,6 @@ class MainModuleFixture implements
      * Executed on saving / submit of the configuration form
      * Can be used to react to changed settings
      * (for example: clearing a specific cache)
-     *
-     * @param array $configurationToSave
-     * @param ServerRequestInterface $request
      */
     public function onSubmit(array $configurationToSave, ServerRequestInterface $request): void
     {
@@ -114,8 +98,6 @@ class MainModuleFixture implements
 
     /**
      * Returns a string array with javascript files that will be rendered after the module
-     *
-     * @return array
      */
     public function getJavaScriptFiles(): array
     {
@@ -124,8 +106,6 @@ class MainModuleFixture implements
 
     /**
      * Returns a string array with css files that will be rendered after the module
-     *
-     * @return array
      */
     public function getCssFiles(): array
     {
@@ -159,9 +139,6 @@ class MainModuleFixture implements
     /**
      * Initialize the module - runs in the TYPO3 middleware stack at an early point
      * may manipulate the current request
-     *
-     * @param ServerRequestInterface $request
-     * @return ServerRequestInterface
      */
     public function enrich(ServerRequestInterface $request): ServerRequestInterface
     {
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php
index 769647a760f02534fa4c84f8c09d13a2cecc6b10..483e4cf94e4581cb34d05592a2f3b9b5fb22b99e 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php
@@ -30,8 +30,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod
     /**
      * Identifier for this Sub-module,
      * for example "preview" or "cache"
-     *
-     * @return string
      */
     public function getIdentifier(): string
     {
@@ -40,8 +38,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod
 
     /**
      * Sub-Module label
-     *
-     * @return string
      */
     public function getLabel(): string
     {
@@ -50,9 +46,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod
 
     /**
      * Sub-Module content as rendered HTML
-     *
-     * @param ModuleData $data
-     * @return string
      */
     public function getContent(ModuleData $data): string
     {
@@ -61,8 +54,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod
 
     /**
      * Settings as HTML form elements (without wrapping form tag or save button)
-     *
-     * @return string
      */
     public function getSettings(): string
     {
@@ -73,18 +64,11 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod
      * Executed on saving / submit of the configuration form
      * Can be used to react to changed settings
      * (for example: clearing a specific cache)
-     *
-     * @param array $configurationToSave
-     * @param ServerRequestInterface $request
      */
     public function onSubmit(array $configurationToSave, ServerRequestInterface $request): void
     {
     }
 
-    /**
-     * @param ServerRequestInterface $request
-     * @return ModuleData
-     */
     public function getDataToStore(ServerRequestInterface $request): ModuleData
     {
         return new ModuleData(['foo' => 'bar']);
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php b/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php
index e752af23b0433d32dadae4ae2d83abf86db323b4..168f989b9cc3f9861376869b16bcbfa26bf40bac 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php
@@ -29,8 +29,6 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 class AdminPanelInitiatorTest extends UnitTestCase
 {
-    protected bool $resetSingletonInstances = true;
-
     /**
      * @test
      */
@@ -54,7 +52,7 @@ class AdminPanelInitiatorTest extends UnitTestCase
         $GLOBALS['BE_USER'] = $userAuthentication;
 
         $controller = $this->getMockBuilder(MainController::class)->disableOriginalConstructor()->getMock();
-        GeneralUtility::setSingletonInstance(MainController::class, $controller);
+        GeneralUtility::addInstance(MainController::class, $controller);
         $handler = $this->getHandlerMock();
         $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
         $request->expects(self::any())->method('withAttribute')->withAnyParameters()->willReturn($request);
@@ -100,10 +98,6 @@ class AdminPanelInitiatorTest extends UnitTestCase
         $this->checkAdminPanelDoesNotCallInitialize($tsConfig, $uc);
     }
 
-    /**
-     * @param array $tsConfig
-     * @param array $uc
-     */
     protected function checkAdminPanelDoesNotCallInitialize(array $tsConfig, array $uc): void
     {
         $userAuthentication = $this->getMockBuilder(FrontendBackendUserAuthentication::class)->getMock();
@@ -112,14 +106,16 @@ class AdminPanelInitiatorTest extends UnitTestCase
         $GLOBALS['BE_USER'] = $userAuthentication;
 
         $controller = $this->getMockBuilder(MainController::class)->disableOriginalConstructor()->getMock();
-        GeneralUtility::setSingletonInstance(MainController::class, $controller);
+        GeneralUtility::addInstance(MainController::class, $controller);
         $handler = $this->getHandlerMock();
         $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
+        $controller->expects(self::never())->method('initialize');
 
         $adminPanelInitiator = new AdminPanelInitiator();
         $adminPanelInitiator->process($request, $handler);
 
-        $controller->expects(self::never())->method('initialize');
+        /** @var MainController&MockObject $controller */
+        $controller = GeneralUtility::makeInstance(MainController::class);
     }
 
     protected function getHandlerMock(): RequestHandlerInterface&MockObject
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php b/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php
index f4ffbd2f267adbd06e733bb501fce3c5985c9d93..865bc223ccb26fee7ec97c7507f9974f1469f10c 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php
@@ -63,9 +63,8 @@ class PreviewModuleTest extends UnitTestCase
         ];
         $configurationService->method('getConfigurationOption')->withAnyParameters()->willReturnMap($valueMap);
 
-        GeneralUtility::setSingletonInstance(ConfigurationService::class, $configurationService);
-
         $previewModule = new PreviewModule();
+        $previewModule->injectConfigurationService($configurationService);
         $previewModule->enrich(new ServerRequest());
 
         self::assertSame($GLOBALS['SIM_EXEC_TIME'], $expectedExecTime, 'EXEC_TIME');
@@ -90,7 +89,6 @@ class PreviewModuleTest extends UnitTestCase
             ['preview', 'showFluidDebug', '0'],
         ];
         $configurationService->method('getConfigurationOption')->withAnyParameters()->willReturnMap($valueMap);
-        GeneralUtility::setSingletonInstance(ConfigurationService::class, $configurationService);
 
         $context = $this->getMockBuilder(Context::class)->getMock();
         $context->method('hasAspect')->with('frontend.preview')->willReturn(false);
@@ -105,6 +103,7 @@ class PreviewModuleTest extends UnitTestCase
         GeneralUtility::setSingletonInstance(Context::class, $context);
 
         $previewModule = new PreviewModule();
+        $previewModule->injectConfigurationService($configurationService);
         $previewModule->enrich($request);
     }
 }
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php b/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php
index c26089ccfe0532c473badd6e7719cb658f832271..aff1200e8a821658302f6063625a6c2dce3ef16a 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php
@@ -127,8 +127,6 @@ class ConfigurationServiceTest extends UnitTestCase
     /**
      * @test
      * @dataProvider getConfigurationOptionEmptyArgumentDataProvider
-     * @param string $identifier
-     * @param string $option
      */
     public function getConfigurationOptionThrowsExceptionOnEmptyArgument(string $identifier, string $option): void
     {
@@ -216,9 +214,6 @@ class ConfigurationServiceTest extends UnitTestCase
         self::assertSame($expected, $this->beUser->uc);
     }
 
-    /**
-     * @param array $userTsAdmPanelConfig
-     */
     private function setUpUserTsConfigForAdmPanel(array $userTsAdmPanelConfig): void
     {
         $this->beUser->method('getTSConfig')->willReturn(
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php b/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php
index 9fe70fcc2cde8d6d37754bc73d99a9deaa6b9047..31e8eca8c97b9d57d5f9cba8b7315dfa31526761 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php
@@ -17,7 +17,6 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Adminpanel\Tests\Unit\Service;
 
-use TYPO3\CMS\Adminpanel\Exceptions\InvalidConfigurationException;
 use TYPO3\CMS\Adminpanel\Service\ModuleLoader;
 use TYPO3\CMS\Adminpanel\Tests\Unit\Fixtures\DisabledMainModuleFixture;
 use TYPO3\CMS\Adminpanel\Tests\Unit\Fixtures\MainModuleFixture;
@@ -49,11 +48,10 @@ class ModuleLoaderTest extends UnitTestCase
     /**
      * @test
      * @dataProvider missingConfigurationDataProvider
-     * @param array $configuration
      */
     public function validateSortAndInitializeModulesThrowsExceptionIfModuleHasMissingConfiguration(array $configuration): void
     {
-        $this->expectException(InvalidConfigurationException::class);
+        $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1519490105);
 
         $moduleLoader = new ModuleLoader();
@@ -88,12 +86,11 @@ class ModuleLoaderTest extends UnitTestCase
 
     /**
      * @test
-     * @dataProvider  invalidConfigurationDataProvider
-     * @param array $configuration
+     * @dataProvider invalidConfigurationDataProvider
      */
     public function validateSortAndInitializeModulesThrowsExceptionIfModuleHasInvalidConfiguration(array $configuration): void
     {
-        $this->expectException(InvalidConfigurationException::class);
+        $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1519490112);
 
         $moduleLoader = new ModuleLoader();
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php b/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php
index 1a15f83d4e8614fa3fd6cabc919d063ea6b5a2eb..ee81f4d92f51dfd43372cccc63cfe8f2cb0c02f4 100644
--- a/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php
+++ b/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php
@@ -71,7 +71,6 @@ class StateUtilityTest extends UnitTestCase
     /**
      * @test
      * @dataProvider tsConfigEnabledDataProvider
-     * @param array $tsConfig
      */
     public function isEnabledReturnsTrueIfAtLeastOneModuleIsEnabled(array $tsConfig): void
     {
@@ -108,7 +107,6 @@ class StateUtilityTest extends UnitTestCase
     /**
      * @test
      * @dataProvider tsConfigDisabledDataProvider
-     * @param array $tsConfig
      */
     public function isEnabledReturnsFalseIfNoModulesEnabled(array $tsConfig): void
     {
@@ -148,8 +146,6 @@ class StateUtilityTest extends UnitTestCase
     /**
      * @test
      * @dataProvider tsConfigHideDataProvider
-     * @param array $tsConfig
-     * @param bool $expected
      */
     public function isHiddenForUserReturnsCorrectValue(array $tsConfig, bool $expected): void
     {
@@ -199,8 +195,6 @@ class StateUtilityTest extends UnitTestCase
     /**
      * @test
      * @dataProvider ucDisplayOpenDataProvider
-     * @param array $uc
-     * @param bool $expected
      */
     public function isOpenForUserReturnsCorrectValue(array $uc, bool $expected): void
     {
@@ -250,8 +244,6 @@ class StateUtilityTest extends UnitTestCase
     /**
      * @test
      * @dataProvider typoScriptDataProvider
-     * @param array $typoScript
-     * @param bool $expected
      */
     public function isActivatedInTypoScriptReturnsCorrectValue(array $typoScript, bool $expected): void
     {