diff --git a/core/core.services.yml b/core/core.services.yml
index 9b35d53c36e42a691eace8c1d1be28e33fecc7bb..ff35f2e003c17e21bee752198782edaaf3f02195 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -306,7 +306,7 @@ services:
       - { name: dynamic_page_cache_response_policy }
   config.manager:
     class: Drupal\Core\Config\ConfigManager
-    arguments: ['@entity_type.manager', '@config.factory', '@config.typed', '@string_translation', '@config.storage', '@event_dispatcher', '@entity.repository']
+    arguments: ['@entity_type.manager', '@config.factory', '@config.typed', '@string_translation', '@config.storage', '@event_dispatcher', '@entity.repository', '@extension.path.resolver']
   config.factory:
     class: Drupal\Core\Config\ConfigFactory
     tags:
@@ -319,7 +319,7 @@ services:
       - { name: event_subscriber }
   config.installer:
     class: Drupal\Core\Config\ConfigInstaller
-    arguments: ['@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher', '%install_profile%']
+    arguments: ['@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher', '%install_profile%', '@extension.path.resolver']
     lazy: true
   config.storage:
     class: Drupal\Core\Config\CachedStorage
@@ -544,6 +544,9 @@ services:
   extension.list.theme_engine:
     class: Drupal\Core\Extension\ThemeEngineExtensionList
     arguments: ['%app.root%', 'theme_engine', '@cache.default', '@info_parser', '@module_handler', '@state', '%install_profile%']
+  extension.path.resolver:
+    class: Drupal\Core\Extension\ExtensionPathResolver
+    arguments: ['@extension.list.module', '@extension.list.profile', '@extension.list.theme', '@extension.list.theme_engine']
   content_uninstall_validator:
     class: Drupal\Core\Entity\ContentUninstallValidator
     tags:
@@ -1517,7 +1520,7 @@ services:
     arguments: ['%app.root%', '@theme_handler', '@cache.bootstrap', '@module_handler']
   theme.registry:
     class: Drupal\Core\Theme\Registry
-    arguments: ['%app.root%', '@cache.default', '@lock', '@module_handler', '@theme_handler', '@theme.initialization', null, '@cache.bootstrap']
+    arguments: ['%app.root%', '@cache.default', '@lock', '@module_handler', '@theme_handler', '@theme.initialization', null, '@cache.bootstrap', '@extension.list.module']
     tags:
       - { name: needs_destruction }
     calls:
@@ -1618,7 +1621,7 @@ services:
       - { name: needs_destruction }
   library.discovery.parser:
     class: Drupal\Core\Asset\LibraryDiscoveryParser
-    arguments: ['%app.root%', '@module_handler', '@theme.manager', '@stream_wrapper_manager', '@library.libraries_directory_file_finder']
+    arguments: ['%app.root%', '@module_handler', '@theme.manager', '@stream_wrapper_manager', '@library.libraries_directory_file_finder', '@extension.path.resolver']
   library.libraries_directory_file_finder:
     class: Drupal\Core\Asset\LibrariesDirectoryFileFinder
     arguments: ['%app.root%', '%site.path%', '@extension.list.profile', '%install_profile%']
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index b6f10263d1da2469394340cc85205ea19ab87844..766931fbd1c6be3db73f13cb01837c4824e1a980 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -160,12 +160,19 @@ class_alias('Drupal\Core\Http\KernelEvent', 'Symfony\Component\HttpKernel\Event\
  *
  * @return string
  *   The filename of the requested item or NULL if the item is not found.
+ *
+ * @deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use
+ *   \Drupal\Core\Extension\ExtensionPathResolver::getPathname() instead.
+ *
+ * @see https://www.drupal.org/node/2940438
  */
 function drupal_get_filename($type, $name, $filename = NULL) {
+  @trigger_error('drupal_get_filename() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
   // Type 'core' only exists to simplify application-level logic; it always maps
   // to the /core directory, whereas $name is ignored. It is only requested via
-  // drupal_get_path(). /core/core.info.yml does not exist, but is required
-  // since drupal_get_path() returns the dirname() of the returned pathname.
+  // \Drupal\Core\Extension\ExtensionList::getPath(). The file
+  // /core/core.info.yml does not exist, but is required since
+  // ExtensionList::getPath() returns the dirname() of the returned pathname.
   if ($type === 'core') {
     return 'core/core.info.yml';
   }
@@ -209,8 +216,15 @@ function drupal_get_filename($type, $name, $filename = NULL) {
  *
  * @return string
  *   The path to the requested item or an empty string if the item is not found.
+ *
+ * @deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use
+ *   \Drupal\Core\Extension\ExtensionPathResolver::getPath() instead.
+ *
+ * @see https://www.drupal.org/node/2940438
+ * @see \Drupal\Core\Extension\ExtensionList::getPath()
  */
 function drupal_get_path($type, $name) {
+  @trigger_error('drupal_get_path() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
   return dirname(drupal_get_filename($type, $name));
 }
 
diff --git a/core/includes/form.inc b/core/includes/form.inc
index d759c8862516b9e8dc221ee13fd89a51d3010d63..4eb5f48bace6c487f17631552ba135ccb16d89f0 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -720,7 +720,7 @@ function template_preprocess_form_element_label(&$variables) {
  *   - file: Path to the file containing the definitions of the 'operations' and
  *     'finished' functions, for instance if they don't reside in the main
  *     .module file. The path should be relative to base_path(), and thus should
- *     be built using drupal_get_path().
+ *     be built using ModuleExtensionList::getPath().
  *   - library: An array of batch-specific CSS and JS libraries.
  *   - url_options: options passed to the \Drupal\Core\Url object when
  *     constructing redirect URLs for the batch.
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 95655c13787722b19be96b62d33ac299942d6868..e488cd7f3641f7e602f4c5d82714332e5565bad8 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -445,12 +445,17 @@ function install_begin_request($class_loader, &$install_state) {
   $listing->setProfileDirectories([]);
   $install_state['profiles'] += $listing->scan('profile');
 
-  // Prime drupal_get_filename()'s static cache.
+  /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
+  $module_list = \Drupal::service('extension.list.module');
+  /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_list */
+  $profile_list = \Drupal::service('extension.list.profile');
+
+  // Prime \Drupal\Core\Extension\ExtensionList::getPathname()'s static cache.
   foreach ($install_state['profiles'] as $name => $profile) {
-    drupal_get_filename('profile', $name, $profile->getPathname());
-    // drupal_get_filename() is called both with 'module' and 'profile', see
+    // Profile path is set in both module and profile lists. See
     // \Drupal\Core\Config\ConfigInstaller::getProfileStorages for example.
-    drupal_get_filename('module', $name, $profile->getPathname());
+    $profile_list->setPathname($name, $profile->getPathname());
+    $module_list->setPathname($name, $profile->getPathname());
   }
 
   if ($profile = _install_select_profile($install_state)) {
@@ -462,10 +467,10 @@ function install_begin_request($class_loader, &$install_state) {
   }
 
   // Before having installed the system module and being able to do a module
-  // rebuild, prime the drupal_get_filename() static cache with the system
-  // module's location.
+  // rebuild, prime the module list static cache with the system module's
+  // location.
   // @todo Remove as part of https://www.drupal.org/node/2186491
-  drupal_get_filename('module', 'system', 'core/modules/system/system.info.yml');
+  $module_list->setPathname('system', 'core/modules/system/system.info.yml');
 
   // Use the language from profile configuration if available.
   if (!empty($install_state['config_install_path']) && $install_state['config']['system.site']) {
@@ -1099,10 +1104,9 @@ function install_base_system(&$install_state) {
   // system.module in order to work.
   \Drupal::service('file.htaccess_writer')->ensure();
 
-  // Prime the drupal_get_filename() static cache with the user module's
-  // exact location.
+  // Prime the module list static cache with the user module's exact location.
   // @todo Remove as part of https://www.drupal.org/node/2186491
-  drupal_get_filename('module', 'user', 'core/modules/user/user.info.yml');
+  \Drupal::service('extension.list.module')->setPathname('user', 'core/modules/user/user.info.yml');
 
   // Install the User module so that installing from configuration works and to
   // ensure the anonymous user is created with a langcode of 'en'.
@@ -1743,7 +1747,7 @@ function install_import_translations(&$install_state) {
       'progress_message' => '',
       'error_message' => t('Error importing translation files'),
       'finished' => 'locale_translation_batch_fetch_finished',
-      'file' => drupal_get_path('module', 'locale') . '/locale.batch.inc',
+      'file' => \Drupal::service('extension.list.module')->getPath('locale') . '/locale.batch.inc',
     ];
     return $batch;
   }
diff --git a/core/includes/install.inc b/core/includes/install.inc
index e68522133271a3604ee6bfa5c1b1f1ebce10cab2..44dc75c1525504f621d2135c3462510370ea44b7 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -1114,7 +1114,7 @@ function install_profile_info($profile, $langcode = 'en') {
       'php' => \Drupal::MINIMUM_PHP,
       'config_install_path' => NULL,
     ];
-    $profile_path = drupal_get_path('profile', $profile);
+    $profile_path = \Drupal::service('extension.list.profile')->getPath($profile);
     $info = \Drupal::service('info_parser')->parse("$profile_path/$profile.info.yml");
     $info += $defaults;
 
diff --git a/core/includes/module.inc b/core/includes/module.inc
index 1ba12ce116e9ff24aa1cb4261b0392762b4e9043..a328b436f3e40bc887ac1d6c1ce3fc212780b957 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -60,8 +60,10 @@ function module_load_include($type, $module, $name = NULL) {
     $name = $module;
   }
 
-  if (function_exists('drupal_get_path')) {
-    $file = DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . "/$name.$type";
+  if (\Drupal::hasService('extension.list.module')) {
+    /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
+    $module_list = \Drupal::service('extension.list.module');
+    $file = DRUPAL_ROOT . '/' . $module_list->getPath($module) . "/$name.$type";
     if (is_file($file)) {
       require_once $file;
       return $file;
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 983baec6167427eae8a0b3b21cd47936c82f4dbd..5631483d45bd6bc8d08c3818747126418445f2c5 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -2,16 +2,17 @@
 
 namespace Drupal\Core\Asset;
 
+use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException;
 use Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException;
 use Drupal\Core\Asset\Exception\InvalidLibraryFileException;
 use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
+use Drupal\Core\Extension\ExtensionPathResolver;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
 use Drupal\Core\Theme\ThemeManagerInterface;
-use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
-use Drupal\Component\Utility\NestedArray;
 
 /**
  * Parses library files to get extension data.
@@ -53,6 +54,13 @@ class LibraryDiscoveryParser {
    */
   protected $librariesDirectoryFileFinder;
 
+  /**
+   * The extension path resolver.
+   *
+   * @var \Drupal\Core\Extension\ExtensionPathResolver
+   */
+  protected $extensionPathResolver;
+
   /**
    * Constructs a new LibraryDiscoveryParser instance.
    *
@@ -66,8 +74,10 @@ class LibraryDiscoveryParser {
    *   The stream wrapper manager.
    * @param \Drupal\Core\Asset\LibrariesDirectoryFileFinder $libraries_directory_file_finder
    *   The libraries directory file finder.
+   * @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
+   *   The extension path resolver.
    */
-  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, StreamWrapperManagerInterface $stream_wrapper_manager, LibrariesDirectoryFileFinder $libraries_directory_file_finder = NULL) {
+  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, StreamWrapperManagerInterface $stream_wrapper_manager, LibrariesDirectoryFileFinder $libraries_directory_file_finder = NULL, ExtensionPathResolver $extension_path_resolver = NULL) {
     $this->root = $root;
     $this->moduleHandler = $module_handler;
     $this->themeManager = $theme_manager;
@@ -77,6 +87,11 @@ public function __construct($root, ModuleHandlerInterface $module_handler, Theme
       $libraries_directory_file_finder = \Drupal::service('library.libraries_directory_file_finder');
     }
     $this->librariesDirectoryFileFinder = $libraries_directory_file_finder;
+    if (!$extension_path_resolver) {
+      @trigger_error('Calling LibraryDiscoveryParser::__construct() without the $extension_path_resolver argument is deprecated in drupal:9.3.0 and is required in drupal:10.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+      $extension_path_resolver = \Drupal::service('extension.path.resolver');
+    }
+    $this->extensionPathResolver = $extension_path_resolver;
   }
 
   /**
@@ -105,7 +120,7 @@ public function buildByExtension($extension) {
       else {
         $extension_type = 'theme';
       }
-      $path = $this->drupalGetPath($extension_type, $extension);
+      $path = $this->extensionPathResolver->getPath($extension_type, $extension);
     }
 
     $libraries = $this->parseLibraryInfo($extension, $path);
@@ -433,9 +448,15 @@ protected function applyLibrariesOverride($libraries, $extension) {
 
   /**
    * Wraps drupal_get_path().
+   *
+   * @deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use
+   *   \Drupal\Core\Extension\ExtensionList::getPath() instead.
+   *
+   * @see https://www.drupal.org/node/2940438
    */
   protected function drupalGetPath($type, $name) {
-    return drupal_get_path($type, $name);
+    @trigger_error(__METHOD__ . ' is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+    return $this->extensionPathResolver->getPath($type, $name);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Batch/BatchBuilder.php b/core/lib/Drupal/Core/Batch/BatchBuilder.php
index 91550e716c4ef9100837b50baa95f423bca52aa9..48eeeea298fe42117e4ae0e7cf77903948dd3a7f 100644
--- a/core/lib/Drupal/Core/Batch/BatchBuilder.php
+++ b/core/lib/Drupal/Core/Batch/BatchBuilder.php
@@ -203,7 +203,8 @@ public function setErrorMessage($message) {
    * Sets the file that contains the callback functions.
    *
    * The path should be relative to base_path(), and thus should be built using
-   * drupal_get_path(). Defaults to {module_name}.module.
+   * \Drupal\Core\Extension\ExtensionList::getPath(). Defaults to
+   * {module_name}.module.
    *
    * The file needs to be set before using ::addOperation(),
    * ::setFinishCallback(), or any other function that uses callbacks from the
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
index 082de18d9197ce2a1c074c70020fa358a25117f5..ec26a7ca0f1969ed76909f6a71d469e8b941f4ec 100644
--- a/core/lib/Drupal/Core/Config/ConfigInstaller.php
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Utility\Crypt;
 use Drupal\Core\Config\Entity\ConfigDependencyManager;
+use Drupal\Core\Extension\ExtensionPathResolver;
 use Drupal\Core\Installer\InstallerKernel;
 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
 
@@ -65,6 +66,13 @@ class ConfigInstaller implements ConfigInstallerInterface {
    */
   protected $installProfile;
 
+  /**
+   * The extension path resolver.
+   *
+   * @var \Drupal\Core\Extension\ExtensionPathResolver
+   */
+  protected $extensionPathResolver;
+
   /**
    * Constructs the configuration installer.
    *
@@ -80,21 +88,28 @@ class ConfigInstaller implements ConfigInstallerInterface {
    *   The event dispatcher.
    * @param string $install_profile
    *   The name of the currently active installation profile.
+   * @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
+   *   The extension path resolver.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher, $install_profile) {
+  public function __construct(ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher, $install_profile, ExtensionPathResolver $extension_path_resolver = NULL) {
     $this->configFactory = $config_factory;
     $this->activeStorages[$active_storage->getCollectionName()] = $active_storage;
     $this->typedConfig = $typed_config;
     $this->configManager = $config_manager;
     $this->eventDispatcher = $event_dispatcher;
     $this->installProfile = $install_profile;
+    if (!$extension_path_resolver) {
+      @trigger_error('Calling ConfigInstaller::__construct() without the $extension_path_resolver argument is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+      $extension_path_resolver = \Drupal::service('extension.path.resolver');
+    }
+    $this->extensionPathResolver = $extension_path_resolver;
   }
 
   /**
    * {@inheritdoc}
    */
   public function installDefaultConfig($type, $name) {
-    $extension_path = $this->drupalGetPath($type, $name);
+    $extension_path = $this->extensionPathResolver->getPath($type, $name);
     // Refresh the schema cache if the extension provides configuration schema
     // or is a theme.
     if (is_dir($extension_path . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY) || $type == 'theme') {
@@ -179,7 +194,7 @@ public function installOptionalConfig(StorageInterface $storage = NULL, $depende
     }
     elseif (!empty($profile)) {
       // Creates a profile storage to search for overrides.
-      $profile_install_path = $this->drupalGetPath('module', $profile) . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
+      $profile_install_path = $this->extensionPathResolver->getPath('module', $profile) . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
       $profile_storage = new FileStorage($profile_install_path, StorageInterface::DEFAULT_COLLECTION);
     }
     else {
@@ -672,7 +687,7 @@ protected function getProfileStorages($installing_name = '') {
     $profile = $this->drupalGetProfile();
     $profile_storages = [];
     if ($profile && $profile != $installing_name) {
-      $profile_path = $this->drupalGetPath('module', $profile);
+      $profile_path = $this->extensionPathResolver->getPath('module', $profile);
       foreach ([InstallStorage::CONFIG_INSTALL_DIRECTORY, InstallStorage::CONFIG_OPTIONAL_DIRECTORY] as $directory) {
         if (is_dir($profile_path . '/' . $directory)) {
           $profile_storages[] = new FileStorage($profile_path . '/' . $directory, StorageInterface::DEFAULT_COLLECTION);
@@ -694,7 +709,7 @@ protected function getProfileStorages($installing_name = '') {
    *   The extension's default configuration directory.
    */
   protected function getDefaultConfigDirectory($type, $name) {
-    return $this->drupalGetPath($type, $name) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
+    return $this->extensionPathResolver->getPath($type, $name) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
   }
 
   /**
@@ -710,9 +725,15 @@ protected function getDefaultConfigDirectory($type, $name) {
    * @return string
    *   The path to the requested item or an empty string if the item is not
    *   found.
+   *
+   * @deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use
+   *   \Drupal\Core\Extension\ExtensionList::getPath() instead.
+   *
+   * @see https://www.drupal.org/node/2940438
    */
   protected function drupalGetPath($type, $name) {
-    return drupal_get_path($type, $name);
+    @trigger_error(__METHOD__ . ' is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+    return $this->extensionPathResolver->getPath($type, $name);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php
index c6ea46f75899dc8496f41fe5b059ace09ec7dad9..2770fe32a198520eb021b0c677f1d329a1fa963e 100644
--- a/core/lib/Drupal/Core/Config/ConfigManager.php
+++ b/core/lib/Drupal/Core/Config/ConfigManager.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Entity\EntityRepositoryInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Extension\ExtensionPathResolver;
 use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\StringTranslation\TranslationInterface;
@@ -77,6 +78,13 @@ class ConfigManager implements ConfigManagerInterface {
    */
   protected $storages;
 
+  /**
+   * The extension path resolver.
+   *
+   * @var \Drupal\Core\Extension\ExtensionPathResolver
+   */
+  protected $extensionPathResolver;
+
   /**
    * Creates ConfigManager objects.
    *
@@ -94,8 +102,10 @@ class ConfigManager implements ConfigManagerInterface {
    *   The event dispatcher.
    * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
    *   The entity repository.
+   * @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
+   *   The extension path resolver.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, TranslationInterface $string_translation, StorageInterface $active_storage, EventDispatcherInterface $event_dispatcher, EntityRepositoryInterface $entity_repository) {
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, TranslationInterface $string_translation, StorageInterface $active_storage, EventDispatcherInterface $event_dispatcher, EntityRepositoryInterface $entity_repository, ExtensionPathResolver $extension_path_resolver = NULL) {
     $this->entityTypeManager = $entity_type_manager;
     $this->configFactory = $config_factory;
     $this->typedConfigManager = $typed_config_manager;
@@ -103,6 +113,11 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Con
     $this->activeStorage = $active_storage;
     $this->eventDispatcher = $event_dispatcher;
     $this->entityRepository = $entity_repository;
+    if (!$extension_path_resolver) {
+      @trigger_error('Calling ConfigManager::__construct without the $extension_path_resolver argument is deprecated in drupal:9.3.0 and is required in drupal:10.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+      $extension_path_resolver = \Drupal::service('extension.path.resolver');
+    }
+    $this->extensionPathResolver = $extension_path_resolver;
   }
 
   /**
@@ -210,7 +225,7 @@ public function uninstall($type, $name) {
       $collection_storage->deleteAll($name . '.');
     }
 
-    $schema_dir = drupal_get_path($type, $name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
+    $schema_dir = $this->extensionPathResolver->getPath($type, $name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
     if (is_dir($schema_dir)) {
       // Refresh the schema cache if uninstalling an extension that provides
       // configuration schema.
diff --git a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
index ccce5457c8d1a88b00c898e0a8c56653e673c2d0..39e13d8476bf403a69ad5bfe68ecc104286f9043 100644
--- a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
+++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
@@ -97,11 +97,14 @@ protected function getAllFolders() {
         unset($modules[$this->installProfile]);
         $profile_list = $listing->scan('profile');
         if ($this->installProfile && isset($profile_list[$this->installProfile])) {
-          // Prime the drupal_get_filename() static cache with the profile info
-          // file location so we can use drupal_get_path() on the active profile
-          // during the module scan.
+          // Prime the \Drupal\Core\Extension\ExtensionList::getPathname()
+          // static cache with the profile info file location so we can use
+          // ExtensionList::getPath() on the active profile during the module
+          // scan.
           // @todo Remove as part of https://www.drupal.org/node/2186491
-          drupal_get_filename('profile', $this->installProfile, $profile_list[$this->installProfile]->getPathname());
+          /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */
+          $profile_extension_list = \Drupal::service('extension.list.profile');
+          $profile_extension_list->setPathname($this->installProfile, $profile_list[$this->installProfile]->getPathname());
         }
         $module_list_scan = $listing->scan('module');
         $module_list = [];
diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php
index 1ad7017f5d9c33c2661c744402d6e4fa5730ba01..a21388b3cbc398560c5351d41d64879ac3e748b8 100644
--- a/core/lib/Drupal/Core/Config/InstallStorage.php
+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -151,18 +151,22 @@ protected function getAllFolders() {
     if (!isset($this->folders)) {
       $this->folders = [];
       $this->folders += $this->getCoreNames();
-      // Perform an ExtensionDiscovery scan as we cannot use drupal_get_path()
-      // yet because the system module may not yet be enabled during install.
+      // Perform an ExtensionDiscovery scan as we cannot use
+      // \Drupal\Core\Extension\ExtensionList::getPath() yet because the system
+      // module may not yet be enabled during install.
       // @todo Remove as part of https://www.drupal.org/node/2186491
       $listing = new ExtensionDiscovery(\Drupal::root());
       if ($profile = \Drupal::installProfile()) {
         $profile_list = $listing->scan('profile');
         if (isset($profile_list[$profile])) {
-          // Prime the drupal_get_filename() static cache with the profile info
-          // file location so we can use drupal_get_path() on the active profile
-          // during the module scan.
+          // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static
+          // cache with the profile info file location so we can use
+          // \Drupal\Core\Extension\ExtensionList::getPath() on the active
+          // profile during the module scan.
           // @todo Remove as part of https://www.drupal.org/node/2186491
-          drupal_get_filename('profile', $profile, $profile_list[$profile]->getPathname());
+          /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */
+          $profile_extension_list = \Drupal::service('extension.list.profile');
+          $profile_extension_list->setPathname($profile, $profile_list[$profile]->getPathname());
           $this->folders += $this->getComponentNames([$profile_list[$profile]]);
         }
       }
@@ -254,7 +258,7 @@ protected function getComponentFolder(Extension $extension) {
    *   The configuration folder name for core.
    */
   protected function getCoreFolder() {
-    return drupal_get_path('core', 'core') . '/' . $this->getCollectionDirectory();
+    return 'core/' . $this->getCollectionDirectory();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Extension/Exception/UnknownExtensionTypeException.php b/core/lib/Drupal/Core/Extension/Exception/UnknownExtensionTypeException.php
new file mode 100644
index 0000000000000000000000000000000000000000..d86d52a5c205fa2458cf9b1f1844a21800a996a9
--- /dev/null
+++ b/core/lib/Drupal/Core/Extension/Exception/UnknownExtensionTypeException.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Drupal\Core\Extension\Exception;
+
+/**
+ * Exception thrown when a specified extension type is not known.
+ */
+class UnknownExtensionTypeException extends \InvalidArgumentException {}
diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
index 134a5ef9ed103567ed62942dd966e503f32e8c4d..266886ba954d43988d4a8d4c87e829ea7cb4740e 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -229,7 +229,7 @@ public function scan($type, $include_tests = NULL) {
   public function setProfileDirectoriesFromSettings() {
     $this->profileDirectories = [];
     if ($profile = \Drupal::installProfile()) {
-      $this->profileDirectories[] = drupal_get_path('profile', $profile);
+      $this->profileDirectories[] = \Drupal::service('extension.list.profile')->getPath($profile);
     }
     return $this;
   }
diff --git a/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d78959db6a60bdc5676d30a2f58296d5d0ea5fa
--- /dev/null
+++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Core\Extension;
+
+use Drupal\Core\Extension\Exception\UnknownExtensionException;
+
+/**
+ * Factory for getting extension lists by type.
+ */
+class ExtensionPathResolver {
+
+  /**
+   * A associative array of ExtensionList objects keyed by type.
+   *
+   * @var \Drupal\Core\Extension\ExtensionList[]
+   */
+  protected $extensionLists;
+
+  /**
+   * ExtensionPathResolver constructor.
+   *
+   * @param \Drupal\Core\Extension\ModuleExtensionList $module_extension_list
+   *   The module extension list.
+   * @param \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list
+   *   The profile extension list.
+   * @param \Drupal\Core\Extension\ThemeExtensionList $theme_extension_list
+   *   The theme extension list.
+   * @param \Drupal\Core\Extension\ThemeEngineExtensionList $theme_engine_extension_list
+   *   The theme engine extension list.
+   */
+  public function __construct(ModuleExtensionList $module_extension_list, ProfileExtensionList $profile_extension_list, ThemeExtensionList $theme_extension_list, ThemeEngineExtensionList $theme_engine_extension_list) {
+    $this->extensionLists['module'] = $module_extension_list;
+    $this->extensionLists['profile'] = $profile_extension_list;
+    $this->extensionLists['theme'] = $theme_extension_list;
+    $this->extensionLists['theme_engine'] = $theme_engine_extension_list;
+  }
+
+  /**
+   * Gets the info file path for the extension.
+   *
+   * @param string $type
+   *   The extension type.
+   * @param string $name
+   *   The extension name.
+   *
+   * @return string|null
+   *   The extension path, or NULL if unknown.
+   */
+  public function getPathname(string $type, string $name): ?string {
+    if ($type === 'core') {
+      return 'core/core.info.yml';
+    }
+    if (!isset($this->extensionLists[$type])) {
+      @trigger_error('Calling getPathname() with an invalid $type parameter is deprecated in drupal:9.3.0 and will throw an \Drupal\Core\Extension\Exception\UnknownExtensionTypeException in drupal:10.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+      return NULL;
+    }
+    try {
+      return $this->extensionLists[$type]->getPathname($name);
+    }
+    catch (UnknownExtensionException $e) {
+      // Catch the exception. This will result in triggering an error.
+      // If the filename is still unknown, create a user-level error message.
+      trigger_error(sprintf('The following %s is missing from the file system: %s', $type, $name), E_USER_WARNING);
+      return NULL;
+    }
+  }
+
+  /**
+   * Gets the extension directory path.
+   *
+   * @param string $type
+   *   The extension type.
+   * @param string $name
+   *   The extension name.
+   *
+   * @return string
+   *   The extension info file path.
+   *
+   * @throws \Drupal\Core\Extension\Exception\UnknownExtensionTypeException
+   *   If the extension type is unknown.
+   * @throws \Drupal\Core\Extension\Exception\UnknownExtensionException
+   *   If the extension is unknown.
+   */
+  public function getPath(string $type, string $name): string {
+    return dirname($this->getPathname($type, $name));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index 4d2290c35e0f6cdef3dfa07d8cc1bdefe7524eb3..bb55a1d852999e7a19c43f866d3272f492d7794d 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -575,7 +575,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    *   The name of the module for which to remove all registered cache bins.
    */
   protected function removeCacheBins($module) {
-    $service_yaml_file = drupal_get_path('module', $module) . "/$module.services.yml";
+    $service_yaml_file = \Drupal::service('extension.list.module')->getPath($module) . "/$module.services.yml";
     if (!file_exists($service_yaml_file)) {
       return;
     }
diff --git a/core/lib/Drupal/Core/Render/theme.api.php b/core/lib/Drupal/Core/Render/theme.api.php
index 413449bef13961b96080030a51cc985a059f0045..47a94de36ee68f0aa9c9e49620d59a98d543bdc3 100644
--- a/core/lib/Drupal/Core/Render/theme.api.php
+++ b/core/lib/Drupal/Core/Render/theme.api.php
@@ -854,7 +854,7 @@ function hook_element_plugin_alter(array &$definitions) {
  */
 function hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
   // Swap out jQuery to use an updated version of the library.
-  $javascript['core/assets/vendor/jquery/jquery.min.js']['data'] = drupal_get_path('module', 'jquery_update') . '/jquery.js';
+  $javascript['core/assets/vendor/jquery/jquery.min.js']['data'] = \Drupal::service('extension.list.module')->getPath('jquery_update') . '/jquery.js';
 }
 
 /**
@@ -1000,7 +1000,7 @@ function hook_library_info_alter(&$libraries, $extension) {
       // Since the replaced library files are no longer located in a directory
       // relative to the original extension, specify an absolute path (relative
       // to DRUPAL_ROOT / base_path()) to the new location.
-      $new_path = '/' . drupal_get_path('module', 'farbtastic_update') . '/js';
+      $new_path = '/' . \Drupal::service('extension.list.module')->getPath('farbtastic_update') . '/js';
       $new_js = [];
       $replacements = [
         $old_path . '/farbtastic.js' => $new_path . '/farbtastic-2.0.js',
@@ -1030,7 +1030,8 @@ function hook_library_info_alter(&$libraries, $extension) {
  */
 function hook_css_alter(&$css, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
   // Remove defaults.css file.
-  unset($css[drupal_get_path('module', 'system') . '/defaults.css']);
+  $file_path = \Drupal::service('extension.list.module')->getPath('system') . '/defaults.css';
+  unset($css[$file_path]);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
index 231c4b5d9a8bfb3274fa5f843bbbe5d37355d3c4..5027566db5501db814ee1c7a5c19334682b15b2e 100644
--- a/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
+++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
@@ -415,13 +415,13 @@ protected function installDefaultThemeFromClassProperty(ContainerInterface $cont
     // not already specified.
     $profile = $container->getParameter('install_profile');
 
-    $default_sync_path = drupal_get_path('profile', $profile) . '/config/sync';
+    $default_sync_path = $container->get('extension.list.profile')->getPath($profile) . '/config/sync';
     $profile_config_storage = new FileStorage($default_sync_path, StorageInterface::DEFAULT_COLLECTION);
     if (!isset($this->defaultTheme) && $profile_config_storage->exists('system.theme')) {
       $this->defaultTheme = $profile_config_storage->read('system.theme')['default'];
     }
 
-    $default_install_path = drupal_get_path('profile', $profile) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
+    $default_install_path = $container->get('extension.list.profile')->getPath($profile) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
     $profile_config_storage = new FileStorage($default_install_path, StorageInterface::DEFAULT_COLLECTION);
     if (!isset($this->defaultTheme) && $profile_config_storage->exists('system.theme')) {
       $this->defaultTheme = $profile_config_storage->read('system.theme')['default'];
diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php
index 094780a10e6a4735e3a326ff24e0220da662865c..08f1b7cea338a57e68a82db074d3a6a6e0830f3e 100644
--- a/core/lib/Drupal/Core/Theme/Registry.php
+++ b/core/lib/Drupal/Core/Theme/Registry.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\DestructableInterface;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Lock\LockBackendInterface;
@@ -155,6 +156,13 @@ class Registry implements DestructableInterface {
    */
   protected $runtimeCache;
 
+  /**
+   * The module list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleList;
+
   /**
    * Constructs a \Drupal\Core\Theme\Registry object.
    *
@@ -174,8 +182,10 @@ class Registry implements DestructableInterface {
    *   (optional) The name of the theme for which to construct the registry.
    * @param \Drupal\Core\Cache\CacheBackendInterface $runtime_cache
    *   The cache backend interface to use for the runtime theme registry data.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
+   *   The module list.
    */
-  public function __construct($root, CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ThemeInitializationInterface $theme_initialization, $theme_name = NULL, CacheBackendInterface $runtime_cache = NULL) {
+  public function __construct($root, CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ThemeInitializationInterface $theme_initialization, $theme_name = NULL, CacheBackendInterface $runtime_cache = NULL, ModuleExtensionList $module_list = NULL) {
     $this->root = $root;
     $this->cache = $cache;
     $this->lock = $lock;
@@ -184,6 +194,11 @@ public function __construct($root, CacheBackendInterface $cache, LockBackendInte
     $this->themeHandler = $theme_handler;
     $this->themeInitialization = $theme_initialization;
     $this->runtimeCache = $runtime_cache;
+    if (!$module_list) {
+      @trigger_error('Calling Registry::__construct() without the $module_list argument is deprecated in drupal:9.3.0 and is required in drupal:10.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+      $module_list = \Drupal::service('extension.list.module');
+    }
+    $this->moduleList = $module_list;
   }
 
   /**
@@ -338,7 +353,7 @@ protected function build() {
     }
     else {
       foreach ($this->moduleHandler->getImplementations('theme') as $module) {
-        $this->processExtension($cache, $module, 'module', $module, $this->getPath($module));
+        $this->processExtension($cache, $module, 'module', $module, $this->moduleList->getPath($module));
       }
       // Only cache this registry if all modules are loaded.
       if ($this->moduleHandler->isLoaded()) {
@@ -835,9 +850,15 @@ public function getPrefixGroupedUserFunctions($prefixes = []) {
    *   The name of the item for which the path is requested.
    *
    * @return string
+   *
+   * @deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use
+   *   \Drupal\Core\Extension\ExtensionList::getPath() instead.
+   *
+   * @see https://www.drupal.org/node/2940438
    */
   protected function getPath($module) {
-    return drupal_get_path('module', $module);
+    @trigger_error(__METHOD__ . ' is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+    return $this->moduleList->getPath($module);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Updater/Module.php b/core/lib/Drupal/Core/Updater/Module.php
index a50eda12bf26572e2b82caa2ce2a4d98a714eb5c..17e02f098c4a74ad2d3ed505ea57bd1c008a506f 100644
--- a/core/lib/Drupal/Core/Updater/Module.php
+++ b/core/lib/Drupal/Core/Updater/Module.php
@@ -13,21 +13,21 @@ class Module extends Updater implements UpdaterInterface {
   /**
    * Returns the directory where a module should be installed.
    *
-   * If the module is already installed, drupal_get_path() will return a valid
-   * path and we should install it there. If we're installing a new module, we
-   * always want it to go into /modules, since that's where all the
-   * documentation recommends users install their modules, and there's no way
-   * that can conflict on a multi-site installation, since the Update manager
-   * won't let you install a new module if it's already found on your system,
-   * and if there was a copy in the top-level we'd see it.
+   * If the module is already installed, ModuleExtensionList::getPath() will
+   * return a valid path and we should install it there. If we're installing a
+   * new module, we always want it to go into /modules, since that's where all
+   * the documentation recommends users install their modules, and there's no
+   * way that can conflict on a multi-site installation, since the Update
+   * manager won't let you install a new module if it's already found on your
+   * system, and if there was a copy in the top-level we'd see it.
    *
    * @return string
    *   The absolute path of the directory.
    */
   public function getInstallDirectory() {
-    if ($this->isInstalled() && ($relative_path = drupal_get_path('module', $this->name))) {
-      // The return value of drupal_get_path() is always relative to the site,
-      // so prepend DRUPAL_ROOT.
+    if ($this->isInstalled() && ($relative_path = \Drupal::service('extension.list.module')->getPath($this->name))) {
+      // The return value of ExtensionList::getPath() is always relative to the
+      // site, so prepend DRUPAL_ROOT.
       return DRUPAL_ROOT . '/' . dirname($relative_path);
     }
     else {
@@ -72,7 +72,7 @@ public static function canUpdateDirectory($directory) {
    * @return bool
    */
   public static function canUpdate($project_name) {
-    return (bool) drupal_get_path('module', $project_name);
+    return (bool) \Drupal::service('extension.list.module')->getPath($project_name);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Updater/Theme.php b/core/lib/Drupal/Core/Updater/Theme.php
index 4b6cd408109adbc9dddbab351d319ff91baeff0d..18b46150644d5676a81b20edc7b5885f46cf33b4 100644
--- a/core/lib/Drupal/Core/Updater/Theme.php
+++ b/core/lib/Drupal/Core/Updater/Theme.php
@@ -13,7 +13,8 @@ class Theme extends Updater implements UpdaterInterface {
   /**
    * Returns the directory where a theme should be installed.
    *
-   * If the theme is already installed, drupal_get_path() will return a valid
+   * If the theme is already installed,
+   * \Drupal::service('extension.list.theme')->getPath() will return a valid
    * path and we should install it there. If we're installing a new theme, we
    * always want it to go into /themes, since that's where all the
    * documentation recommends users install their themes, and there's no way
@@ -25,9 +26,10 @@ class Theme extends Updater implements UpdaterInterface {
    *   The absolute path of the directory.
    */
   public function getInstallDirectory() {
-    if ($this->isInstalled() && ($relative_path = drupal_get_path('theme', $this->name))) {
-      // The return value of drupal_get_path() is always relative to the site,
-      // so prepend DRUPAL_ROOT.
+    if ($this->isInstalled() && ($relative_path = \Drupal::service('extension.list.theme')->getPath($this->name))) {
+      // The return value of
+      // \Drupal::service('extension.list.theme')->getPath() is always relative
+      // to the site, so prepend DRUPAL_ROOT.
       return DRUPAL_ROOT . '/' . dirname($relative_path);
     }
     else {
@@ -71,7 +73,7 @@ public static function canUpdateDirectory($directory) {
    * @return bool
    */
   public static function canUpdate($project_name) {
-    return (bool) drupal_get_path('theme', $project_name);
+    return (bool) \Drupal::service('extension.list.theme')->getPath($project_name);
   }
 
   /**
diff --git a/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php b/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php
index 6aa528e9e23c6d4d0c766170051a36b8576b1c07..a1ca558c30a2379f3b9683521aee5cfd877d7421 100644
--- a/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php
+++ b/core/modules/aggregator/tests/src/Functional/AggregatorTestBase.php
@@ -356,7 +356,7 @@ public function getEmptyOpml() {
    *   Path to the feed.
    */
   public function getRSS091Sample() {
-    return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/modules/aggregator_test/aggregator_test_rss091.xml';
+    return $GLOBALS['base_url'] . '/' . $this->getModulePath('aggregator') . '/tests/modules/aggregator_test/aggregator_test_rss091.xml';
   }
 
   /**
@@ -368,7 +368,7 @@ public function getRSS091Sample() {
   public function getAtomSample() {
     // The content of this sample ATOM feed is based directly off of the
     // example provided in RFC 4287.
-    return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/modules/aggregator_test/aggregator_test_atom.xml';
+    return $GLOBALS['base_url'] . '/' . $this->getModulePath('aggregator') . '/tests/modules/aggregator_test/aggregator_test_atom.xml';
   }
 
   /**
@@ -378,7 +378,7 @@ public function getAtomSample() {
    *   Path to the feed.
    */
   public function getHtmlEntitiesSample() {
-    return $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'aggregator') . '/tests/modules/aggregator_test/aggregator_test_title_entities.xml';
+    return $GLOBALS['base_url'] . '/' . $this->getModulePath('aggregator') . '/tests/modules/aggregator_test/aggregator_test_title_entities.xml';
   }
 
   /**
diff --git a/core/modules/ckeditor/ckeditor.api.php b/core/modules/ckeditor/ckeditor.api.php
index 01a1e17ceb62796216c1988233a6031f35830c70..657482b1362b75a53040181f38286213ea313825 100644
--- a/core/modules/ckeditor/ckeditor.api.php
+++ b/core/modules/ckeditor/ckeditor.api.php
@@ -53,7 +53,7 @@ function hook_ckeditor_plugin_info_alter(array &$plugins) {
  * @see _ckeditor_theme_css()
  */
 function hook_ckeditor_css_alter(array &$css, Editor $editor) {
-  $css[] = drupal_get_path('module', 'mymodule') . '/css/mymodule-ckeditor.css';
+  $css[] = \Drupal::service('extension.list.module')->getPath('mymodule') . '/css/mymodule-ckeditor.css';
 }
 
 /**
diff --git a/core/modules/ckeditor/ckeditor.module b/core/modules/ckeditor/ckeditor.module
index 668e23e34eb35850bdc2b86d805ab53310d1e5ca..c7fbe664e8dbae405c1a21d8dbb70e35cc782bba 100644
--- a/core/modules/ckeditor/ckeditor.module
+++ b/core/modules/ckeditor/ckeditor.module
@@ -71,7 +71,7 @@ function ckeditor_ckeditor_css_alter(array &$css, Editor $editor) {
   // editor uses the filter_caption filter. This is used by the included
   // CKEditor DrupalImageCaption plugin.
   if ($editor->getFilterFormat()->filters('filter_caption')->status) {
-    $css[] = drupal_get_path('module', 'filter') . '/css/filter.caption.css';
+    $css[] = \Drupal::service('extension.list.module')->getPath('filter') . '/css/filter.caption.css';
   }
 }
 
@@ -91,8 +91,10 @@ function _ckeditor_theme_css($theme = NULL) {
   if (!isset($theme)) {
     $theme = \Drupal::config('system.theme')->get('default');
   }
-  if (isset($theme) && $theme_path = drupal_get_path('theme', $theme)) {
-    $info = \Drupal::service('extension.list.theme')->getExtensionInfo($theme);
+  /** @var \Drupal\Core\Extension\ThemeExtensionList $theme_list */
+  $theme_list = \Drupal::service('extension.list.theme');
+  if (isset($theme) && $theme_path = $theme_list->getPath($theme)) {
+    $info = $theme_list->getExtensionInfo($theme);
     if (isset($info['ckeditor_stylesheets'])) {
       $css = $info['ckeditor_stylesheets'];
       foreach ($css as $key => $url) {
diff --git a/core/modules/ckeditor/src/CKEditorPluginBase.php b/core/modules/ckeditor/src/CKEditorPluginBase.php
index af284fc71bfc7def0b70f07568aa7a5ad51b6924..aa76200519cdc5bd2793145da4e4fcd69d341283 100644
--- a/core/modules/ckeditor/src/CKEditorPluginBase.php
+++ b/core/modules/ckeditor/src/CKEditorPluginBase.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\ckeditor;
 
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\editor\Entity\Editor;
 
@@ -30,6 +31,44 @@
  */
 abstract class CKEditorPluginBase extends PluginBase implements CKEditorPluginInterface, CKEditorPluginButtonsInterface {
 
+  /**
+   * The module list service.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleList;
+
+  /**
+   * Gets the module list service.
+   *
+   * @return \Drupal\Core\Extension\ModuleExtensionList
+   *   The module extension list service.
+   */
+  protected function getModuleList(): ModuleExtensionList {
+    if (!$this->moduleList) {
+      $this->moduleList = \Drupal::service('extension.list.module');
+    }
+    return $this->moduleList;
+  }
+
+  /**
+   * Gets the Drupal-root relative installation directory of a module.
+   *
+   * @param string $module_name
+   *   The machine name of the module.
+   *
+   * @return string
+   *   The module installation directory.
+   *
+   * @throws \InvalidArgumentException
+   *   If there is no extension with the supplied machine name.
+   *
+   * @see \Drupal\Core\Extension\ExtensionList::getPath()
+   */
+  protected function getModulePath(string $module_name): string {
+    return $this->getModuleList()->getPath($module_name);
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
index 587cf85e7811fd98513361f0df515dfcc50a8f03..26e6300d13e226a3b7ad2b2219192f250682d299 100644
--- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
@@ -22,7 +22,7 @@ class DrupalImage extends CKEditorPluginBase implements CKEditorPluginConfigurab
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimage/plugin.js';
+    return $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/plugin.js';
   }
 
   /**
@@ -51,7 +51,7 @@ public function getButtons() {
     return [
       'DrupalImage' => [
         'label' => $this->t('Image'),
-        'image' => drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimage/icons/drupalimage.png',
+        'image' => $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/icons/drupalimage.png',
       ],
     ];
   }
diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
index 45b97e77bc1c109167a6d15b2fa53ce2103d0a3f..18afc56f3de48e1614743daed8f002a3d2315d04 100644
--- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
@@ -2,11 +2,13 @@
 
 namespace Drupal\ckeditor\Plugin\CKEditorPlugin;
 
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\editor\Entity\Editor;
 use Drupal\ckeditor\CKEditorPluginInterface;
 use Drupal\ckeditor\CKEditorPluginContextualInterface;
 use Drupal\ckeditor\CKEditorPluginCssInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines the "drupalimagecaption" plugin.
@@ -17,7 +19,27 @@
  *   module = "ckeditor"
  * )
  */
-class DrupalImageCaption extends PluginBase implements CKEditorPluginInterface, CKEditorPluginContextualInterface, CKEditorPluginCssInterface {
+class DrupalImageCaption extends PluginBase implements CKEditorPluginInterface, CKEditorPluginContextualInterface, CKEditorPluginCssInterface, ContainerFactoryPluginInterface {
+
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleList;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    $instance = new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+    );
+    $instance->moduleList = $container->get('extension.list.module');
+    return $instance;
+  }
 
   /**
    * {@inheritdoc}
@@ -46,7 +68,7 @@ public function getLibraries(Editor $editor) {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';
+    return $this->moduleList->getPath('ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';
   }
 
   /**
@@ -70,7 +92,7 @@ public function getConfig(Editor $editor) {
    */
   public function getCssFiles(Editor $editor) {
     return [
-      drupal_get_path('module', 'ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',
+      $this->moduleList->getPath('ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',
     ];
   }
 
diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalLink.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalLink.php
index a6363f6b73fd13528da9328f31e95da32dd9c818..55db9294b73c7a245104c47bfcf349f5f351abc0 100644
--- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalLink.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalLink.php
@@ -20,7 +20,7 @@ class DrupalLink extends CKEditorPluginBase {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor') . '/js/plugins/drupallink/plugin.js';
+    return $this->getModulePath('ckeditor') . '/js/plugins/drupallink/plugin.js';
   }
 
   /**
@@ -46,7 +46,7 @@ public function getConfig(Editor $editor) {
    * {@inheritdoc}
    */
   public function getButtons() {
-    $path = drupal_get_path('module', 'ckeditor') . '/js/plugins/drupallink';
+    $path = $this->getModulePath('ckeditor') . '/js/plugins/drupallink';
     return [
       'DrupalLink' => [
         'label' => $this->t('Link'),
diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
index 8b9afe20145acd188ca0b125fd22894e41448150..5334bae991da5755d54fa6d010980464e2cb0f30 100644
--- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
@@ -129,7 +129,7 @@ public function settingsForm(array $form, FormStateInterface $form_state, Editor
    */
   public function getCssFiles(Editor $editor) {
     return [
-        drupal_get_path('module', 'ckeditor') . '/css/plugins/language/ckeditor.language.css',
+      $this->getModulePath('ckeditor') . '/css/plugins/language/ckeditor.language.css',
     ];
   }
 
diff --git a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
index fd5a338b7a2ec40de5be06524b9e8a2614420f7c..923bf91f9bbedd917aad5550b3cdb3646359eaaf 100644
--- a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
+++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\ckeditor\Plugin\Editor;
 
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\ckeditor\CKEditorPluginManager;
 use Drupal\Core\File\FileUrlGeneratorInterface;
@@ -73,6 +74,13 @@ class CKEditor extends EditorBase implements ContainerFactoryPluginInterface {
    */
   protected $state;
 
+  /**
+   * The module list service.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleList;
+
   /**
    * Constructs a \Drupal\ckeditor\Plugin\Editor\CKEditor object.
    *
@@ -94,8 +102,10 @@ class CKEditor extends EditorBase implements ContainerFactoryPluginInterface {
    *   The state key/value store.
    * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator
    *   The file URL generator.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
+   *   The module list service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, CKEditorPluginManager $ckeditor_plugin_manager, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, RendererInterface $renderer, StateInterface $state, FileUrlGeneratorInterface $file_url_generator = NULL) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, CKEditorPluginManager $ckeditor_plugin_manager, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, RendererInterface $renderer, StateInterface $state, FileUrlGeneratorInterface $file_url_generator = NULL, ModuleExtensionList $module_list = NULL) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->ckeditorPluginManager = $ckeditor_plugin_manager;
     $this->moduleHandler = $module_handler;
@@ -107,6 +117,11 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
       $file_url_generator = \Drupal::service('file_url_generator');
     }
     $this->fileUrlGenerator = $file_url_generator;
+    if (!$module_list) {
+      @trigger_error('Calling CKEditor::__construct() without the $module_list argument is deprecated in drupal:9.3.0 and is required in drupal:10.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
+      $module_list = \Drupal::service('extension.list.module');
+    }
+    $this->moduleList = $module_list;
   }
 
   /**
@@ -122,7 +137,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('language_manager'),
       $container->get('renderer'),
       $container->get('state'),
-      $container->get('file_url_generator')
+      $container->get('file_url_generator'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -442,8 +458,8 @@ public function buildToolbarJSSetting(Editor $editor) {
    */
   public function buildContentsCssJSSetting(Editor $editor) {
     $css = [
-      drupal_get_path('module', 'ckeditor') . '/css/ckeditor-iframe.css',
-      drupal_get_path('module', 'system') . '/css/components/align.module.css',
+      $this->moduleList->getPath('ckeditor') . '/css/ckeditor-iframe.css',
+      $this->moduleList->getPath('system') . '/css/components/align.module.css',
     ];
     $this->moduleHandler->alter('ckeditor_css', $css, $editor);
     // Get a list of all enabled plugins' iframe instance CSS files.
diff --git a/core/modules/ckeditor/tests/modules/ckeditor_test.module b/core/modules/ckeditor/tests/modules/ckeditor_test.module
index a75ad86354cc611b0ccfedf34e545bdfd503b136..44e68834aa301f6f8121a76e8e8700ce85f7dee6 100644
--- a/core/modules/ckeditor/tests/modules/ckeditor_test.module
+++ b/core/modules/ckeditor/tests/modules/ckeditor_test.module
@@ -11,5 +11,5 @@
  * Implements hook_ckeditor_css_alter().
  */
 function ckeditor_test_ckeditor_css_alter(array &$css, Editor $editor) {
-  $css[] = drupal_get_path('module', 'ckeditor_test') . '/ckeditor_test.css';
+  $css[] = \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/ckeditor_test.css';
 }
diff --git a/core/modules/ckeditor/tests/modules/src/Form/AjaxCssForm.php b/core/modules/ckeditor/tests/modules/src/Form/AjaxCssForm.php
index 504293341000793813aa8ad10e4588bd3704983c..fd8ef0e58d77c604aa19a43f380620509ead233f 100644
--- a/core/modules/ckeditor/tests/modules/src/Form/AjaxCssForm.php
+++ b/core/modules/ckeditor/tests/modules/src/Form/AjaxCssForm.php
@@ -107,7 +107,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    */
   protected function generateResponse($editor_id) {
     // Build a URL to the style sheet that will be added.
-    $url = drupal_get_path('module', 'ckeditor_test') . '/css/test.css';
+    $url = \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/css/test.css';
     $url = $this->fileUrlGenerator->generateString($url);
 
     $response = new AjaxResponse();
diff --git a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/Llama.php b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/Llama.php
index 3b8951caec91ff98349365371580a0d90c4135bf..b724ff159252115359919856ba138aceca6e467d 100644
--- a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/Llama.php
+++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/Llama.php
@@ -4,7 +4,9 @@
 
 use Drupal\ckeditor\CKEditorPluginInterface;
 use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\editor\Entity\Editor;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines the "Llama" plugin, with a CKEditor "llama" feature.
@@ -24,7 +26,27 @@
  *   label = @Translation("Llama")
  * )
  */
-class Llama extends PluginBase implements CKEditorPluginInterface {
+class Llama extends PluginBase implements CKEditorPluginInterface, ContainerFactoryPluginInterface {
+
+  /**
+   * The module list service.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleList;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    $instance = new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+    );
+    $instance->moduleList = $container->get('extension.list.module');
+    return $instance;
+  }
 
   /**
    * {@inheritdoc}
@@ -51,7 +73,7 @@ public function isInternal() {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor_test') . '/js/llama.js';
+    return $this->moduleList->getPath('ckeditor_test') . '/js/llama.js';
   }
 
   /**
diff --git a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaButton.php b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaButton.php
index b357811c06c37f1bec0f987e8f9d41b3fa322c8f..646eaa6d25da097f16c0a7b9c62f7336d920defe 100644
--- a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaButton.php
+++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaButton.php
@@ -29,7 +29,7 @@ public function getButtons() {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor_test') . '/js/llama_button.js';
+    return $this->moduleList->getPath('ckeditor_test') . '/js/llama_button.js';
   }
 
 }
diff --git a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextual.php b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextual.php
index 5ece17acadf9e1c9d03ae5ae07376e1b1cfa588e..4fcbdb142b360e5b283ddefeb80663d4fa3056d2 100644
--- a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextual.php
+++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextual.php
@@ -35,7 +35,7 @@ public function isEnabled(Editor $editor) {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor_test') . '/js/llama_contextual.js';
+    return $this->moduleList->getPath('ckeditor_test') . '/js/llama_contextual.js';
   }
 
 }
diff --git a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextualAndButton.php b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextualAndButton.php
index 450a3966c110e24d0eccda98e3163f78f1b6d57b..3033904f295281d7e8608ee23740399abeb3b7b0 100644
--- a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextualAndButton.php
+++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextualAndButton.php
@@ -50,7 +50,7 @@ public function getButtons() {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor_test') . '/js/llama_contextual_and_button.js';
+    return $this->moduleList->getPath('ckeditor_test') . '/js/llama_contextual_and_button.js';
   }
 
   /**
diff --git a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaCss.php b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaCss.php
index 1312658d70ebf7c8d58bbca968ecb4ceda0a7beb..23ffc8b5c96d3ba68fe52a8f7191b040a8ce93e2 100644
--- a/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaCss.php
+++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaCss.php
@@ -32,7 +32,7 @@ public function getButtons() {
    */
   public function getCssFiles(Editor $editor) {
     return [
-      drupal_get_path('module', 'ckeditor_test') . '/css/llama.css',
+      $this->moduleList->getPath('ckeditor_test') . '/css/llama.css',
     ];
   }
 
@@ -40,7 +40,7 @@ public function getCssFiles(Editor $editor) {
    * {@inheritdoc}
    */
   public function getFile() {
-    return drupal_get_path('module', 'ckeditor_test') . '/js/llama_css.js';
+    return $this->moduleList->getPath('ckeditor_test') . '/js/llama_css.js';
   }
 
 }
diff --git a/core/modules/ckeditor/tests/src/Functional/CKEditorLoadingTest.php b/core/modules/ckeditor/tests/src/Functional/CKEditorLoadingTest.php
index 1b7a404f4468a8cb2846c394ab46485f579b0e23..cf34e427d8cf16e1834d2ed34041fe885d28ec4f 100644
--- a/core/modules/ckeditor/tests/src/Functional/CKEditorLoadingTest.php
+++ b/core/modules/ckeditor/tests/src/Functional/CKEditorLoadingTest.php
@@ -101,11 +101,11 @@ public function testLoading() {
     // Verify that a single text format hidden input does not exist on the page.
     $this->assertSession()->elementNotExists('xpath', '//input[@type="hidden" and contains(@class, "editor")]');
     // Verify that CKEditor glue JS is absent.
-    $this->assertNoRaw(drupal_get_path('module', 'ckeditor') . '/js/ckeditor.js');
+    $this->assertNoRaw($this->getModulePath('ckeditor') . '/js/ckeditor.js');
 
     // On pages where there would never be a text editor, CKEditor JS is absent.
     $this->drupalGet('user');
-    $this->assertNoRaw(drupal_get_path('module', 'ckeditor') . '/js/ckeditor.js');
+    $this->assertNoRaw($this->getModulePath('ckeditor') . '/js/ckeditor.js');
 
     // The normal user:
     // - has access to 2 text formats;
diff --git a/core/modules/ckeditor/tests/src/Kernel/CKEditorPluginManagerTest.php b/core/modules/ckeditor/tests/src/Kernel/CKEditorPluginManagerTest.php
index 32f1c77c8f329bc0c1478f4cb05fe33139a73aec..8de0c7038676e7ae99d1678149014f1cd8a0d8e5 100644
--- a/core/modules/ckeditor/tests/src/Kernel/CKEditorPluginManagerTest.php
+++ b/core/modules/ckeditor/tests/src/Kernel/CKEditorPluginManagerTest.php
@@ -65,8 +65,8 @@ public function testEnabledPlugins() {
     sort($definitions);
     $this->assertSame(['drupalimage', 'drupalimagecaption', 'drupallink', 'internal', 'language', 'stylescombo'], $definitions, 'No CKEditor plugins found besides the built-in ones.');
     $enabled_plugins = [
-      'drupalimage' => drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimage/plugin.js',
-      'drupallink' => drupal_get_path('module', 'ckeditor') . '/js/plugins/drupallink/plugin.js',
+      'drupalimage' => $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/plugin.js',
+      'drupallink' => $this->getModulePath('ckeditor') . '/js/plugins/drupallink/plugin.js',
     ];
     $this->assertSame($enabled_plugins, $this->manager->getEnabledPluginFiles($editor), 'Only built-in plugins are enabled.');
     $this->assertSame(['internal' => NULL] + $enabled_plugins, $this->manager->getEnabledPluginFiles($editor, TRUE), 'Only the "internal" plugin is enabled.');
@@ -107,10 +107,10 @@ public function testEnabledPlugins() {
     $editor->setSettings($settings);
     $editor->save();
     $file = [];
-    $file['b'] = drupal_get_path('module', 'ckeditor_test') . '/js/llama_button.js';
-    $file['c'] = drupal_get_path('module', 'ckeditor_test') . '/js/llama_contextual.js';
-    $file['cb'] = drupal_get_path('module', 'ckeditor_test') . '/js/llama_contextual_and_button.js';
-    $file['css'] = drupal_get_path('module', 'ckeditor_test') . '/js/llama_css.js';
+    $file['b'] = $this->getModulePath('ckeditor_test') . '/js/llama_button.js';
+    $file['c'] = $this->getModulePath('ckeditor_test') . '/js/llama_contextual.js';
+    $file['cb'] = $this->getModulePath('ckeditor_test') . '/js/llama_contextual_and_button.js';
+    $file['css'] = $this->getModulePath('ckeditor_test') . '/js/llama_css.js';
     $expected = $enabled_plugins + ['llama_button' => $file['b'], 'llama_contextual_and_button' => $file['cb']];
     $this->assertSame($expected, $this->manager->getEnabledPluginFiles($editor), 'The LlamaButton and LlamaContextualAndButton plugins are enabled.');
     $this->assertSame(['internal' => NULL] + $expected, $this->manager->getEnabledPluginFiles($editor, TRUE), 'The LlamaButton and LlamaContextualAndButton plugins are enabled.');
@@ -157,7 +157,7 @@ public function testCssFiles() {
 
     // Case 2: CKEditor iframe instance CSS file.
     $expected = [
-      'llama_css' => [drupal_get_path('module', 'ckeditor_test') . '/css/llama.css'],
+      'llama_css' => [$this->getModulePath('ckeditor_test') . '/css/llama.css'],
     ];
     $this->assertSame($expected, $this->manager->getCssFiles($editor), 'Iframe instance CSS file found.');
   }
diff --git a/core/modules/ckeditor/tests/src/Kernel/CKEditorTest.php b/core/modules/ckeditor/tests/src/Kernel/CKEditorTest.php
index ba994452dae9eb38d98f54f6d612bb411f05716f..68fd7a6073190c2200bb9cc0677e8bf8b591e6f4 100644
--- a/core/modules/ckeditor/tests/src/Kernel/CKEditorTest.php
+++ b/core/modules/ckeditor/tests/src/Kernel/CKEditorTest.php
@@ -265,7 +265,7 @@ public function testBuildContentsCssJSSetting() {
 
     // Enable the editor_test module, which implements hook_ckeditor_css_alter().
     $this->enableModules(['ckeditor_test']);
-    $expected[] = $this->fileUrlGenerator->generateString(drupal_get_path('module', 'ckeditor_test') . '/ckeditor_test.css') . $query_string;
+    $expected[] = $this->fileUrlGenerator->generateString($this->getModulePath('ckeditor_test') . '/ckeditor_test.css') . $query_string;
     $this->assertSame($expected, $this->ckeditor->buildContentsCssJSSetting($editor), '"contentsCss" configuration part of JS settings built correctly while a hook_ckeditor_css_alter() implementation exists.');
 
     // Enable LlamaCss plugin, which adds an additional CKEditor stylesheet.
@@ -277,7 +277,7 @@ public function testBuildContentsCssJSSetting() {
     $settings['toolbar']['rows'][0][0]['items'][] = 'LlamaCSS';
     $editor->setSettings($settings);
     $editor->save();
-    $expected[] = $this->fileUrlGenerator->generateString(drupal_get_path('module', 'ckeditor_test') . '/css/llama.css') . $query_string;
+    $expected[] = $this->fileUrlGenerator->generateString($this->getModulePath('ckeditor_test') . '/css/llama.css') . $query_string;
     $this->assertSame($expected, $this->ckeditor->buildContentsCssJSSetting($editor), '"contentsCss" configuration part of JS settings built correctly while a CKEditorPluginInterface implementation exists.');
 
     // Enable the Bartik theme, which specifies a CKEditor stylesheet.
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index a2c0cab28e97a7ace291633a8bc022e2e64467d2..56b1b9d2ff1ce095cd43f0d0fc0aa7eaf9566ddf 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -129,7 +129,7 @@ function color_get_info($theme) {
     return $theme_info[$theme];
   }
 
-  $path = drupal_get_path('theme', $theme);
+  $path = \Drupal::service('extension.list.theme')->getPath($theme);
   $file = \Drupal::root() . '/' . $path . '/color/color.inc';
   if ($path && file_exists($file)) {
     include $file;
@@ -286,7 +286,13 @@ function template_preprocess_color_scheme_form(&$variables) {
   }
 
   // Attempt to load preview HTML if the theme provides it.
-  $preview_html_path = \Drupal::root() . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html');
+  $preview_html_path = \Drupal::root() . '/';
+  if (isset($info['preview_html'])) {
+    $preview_html_path .= \Drupal::service('extension.list.theme')->getPath($theme) . '/' . $info['preview_html'];
+  }
+  else {
+    $preview_html_path .= \Drupal::service('extension.list.module')->getPath('color') . '/preview.html';
+  }
   $variables['html_preview']['#markup'] = file_get_contents($preview_html_path);
 }
 
@@ -386,7 +392,7 @@ function color_scheme_form_submit($form, FormStateInterface $form_state) {
   // Make sure enough memory is available.
   if (isset($info['base_image'])) {
     // Fetch source image dimensions.
-    $source = drupal_get_path('theme', $theme) . '/' . $info['base_image'];
+    $source = \Drupal::service('extension.list.theme')->getPath($theme) . '/' . $info['base_image'];
     list($width, $height) = getimagesize($source);
 
     // We need at least a copy of the source and a target buffer of the same
@@ -434,7 +440,7 @@ function color_scheme_form_submit($form, FormStateInterface $form_state) {
   }
   $paths['target'] = $paths['target'] . '/';
   $paths['id'] = $id;
-  $paths['source'] = drupal_get_path('theme', $theme) . '/';
+  $paths['source'] = \Drupal::service('extension.list.theme')->getPath($theme) . '/';
   $paths['files'] = $paths['map'] = [];
 
   // Save palette and logo location.
diff --git a/core/modules/comment/tests/src/Functional/CommentCSSTest.php b/core/modules/comment/tests/src/Functional/CommentCSSTest.php
index fb104b4f7ff2d2b67a0eea760d430ac0a6e163b6..3aee0b75753ca31852e0e8807cb48af4f653c429 100644
--- a/core/modules/comment/tests/src/Functional/CommentCSSTest.php
+++ b/core/modules/comment/tests/src/Functional/CommentCSSTest.php
@@ -115,7 +115,7 @@ public function testCommentClasses() {
         // user (the viewer) was the author of the comment. We do this in Java-
         // Script to prevent breaking the render cache.
         $this->assertCount(1, $this->xpath('//*[contains(@class, "comment") and @data-comment-user-id="' . $case['comment_uid'] . '"]'), 'data-comment-user-id attribute is set on comment.');
-        $this->assertRaw(drupal_get_path('module', 'comment') . '/js/comment-by-viewer.js');
+        $this->assertRaw($this->getModulePath('comment') . '/js/comment-by-viewer.js');
       }
 
       // Verify the unpublished class.
diff --git a/core/modules/config/tests/src/Functional/ConfigInstallProfileOverrideTest.php b/core/modules/config/tests/src/Functional/ConfigInstallProfileOverrideTest.php
index 4b723d3b4e00afad119cf4d2222fc42c6b677d5f..f367a1377c26a5df63324b2372aeea1c0e20f526 100644
--- a/core/modules/config/tests/src/Functional/ConfigInstallProfileOverrideTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigInstallProfileOverrideTest.php
@@ -57,7 +57,7 @@ public function testInstallProfileConfigOverwrite() {
     // Verify that the original data matches. We have to read the module config
     // file directly, because the install profile default system.cron.yml
     // configuration file was used to create the active configuration.
-    $config_dir = drupal_get_path('module', 'system') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
+    $config_dir = $this->getModulePath('system') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
     $this->assertDirectoryExists($config_dir);
     $source_storage = new FileStorage($config_dir);
     $data = $source_storage->read($config_name);
@@ -101,7 +101,7 @@ public function testInstallProfileConfigOverwrite() {
     // Ensure that optional configuration from a profile is not created if
     // dependencies are not met. Cannot use the entity system since the entity
     // type does not exist.
-    $optional_dir = drupal_get_path('module', 'testing_config_overrides') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
+    $optional_dir = $this->getModulePath('testing_config_overrides') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
     $optional_storage = new FileStorage($optional_dir);
     foreach (['config_test.dynamic.dotted.default', 'config_test.dynamic.override', 'config_test.dynamic.override_unmet'] as $id) {
       $this->assertTrue(\Drupal::config($id)->isNew(), "The config_test entity $id contained in the profile's optional directory does not exist.");
diff --git a/core/modules/datetime_range/tests/src/Kernel/Views/EntityTypeWithoutViewsDataTest.php b/core/modules/datetime_range/tests/src/Kernel/Views/EntityTypeWithoutViewsDataTest.php
index d154b00a47c0bf735e1219a9dc06757dc907a834..e1710eee68456ce30cb9a9fbaa10036b30c41777 100644
--- a/core/modules/datetime_range/tests/src/Kernel/Views/EntityTypeWithoutViewsDataTest.php
+++ b/core/modules/datetime_range/tests/src/Kernel/Views/EntityTypeWithoutViewsDataTest.php
@@ -34,7 +34,7 @@ class EntityTypeWithoutViewsDataTest extends KernelTestBase {
    * @see datetime_test_entity_type_alter()
    */
   public function testEntityTypeWithoutViewsData() {
-    $view_yaml = drupal_get_path('module', 'taxonomy') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY . '/views.view.taxonomy_term.yml';
+    $view_yaml = $this->getModulePath('taxonomy') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY . '/views.view.taxonomy_term.yml';
     $values = Yaml::decode(file_get_contents($view_yaml));
     $this->assertEquals(SAVED_NEW, View::create($values)->save());
   }
diff --git a/core/modules/dblog/tests/src/Functional/DbLogTest.php b/core/modules/dblog/tests/src/Functional/DbLogTest.php
index 9853314eeb7e8e8086ac08e9945ba2e11ca34d08..61484cddb5904c6703dcb1c357d20a1ac8d38c82 100644
--- a/core/modules/dblog/tests/src/Functional/DbLogTest.php
+++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
@@ -897,7 +897,7 @@ public function testBacktrace() {
       '%type' => 'User warning',
       '@message' => 'Drupal & awesome',
       '%function' => ErrorTestController::class . '->generateWarnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
 
     // Check if the full message displays on the details page and backtrace is a
diff --git a/core/modules/editor/tests/src/Functional/EditorLoadingTest.php b/core/modules/editor/tests/src/Functional/EditorLoadingTest.php
index 025e6ab2e69a331313fc89ca0ee883c2eec4acba..10cafa12a2ba02aa2ebbe61046fbb016f7a55d63 100644
--- a/core/modules/editor/tests/src/Functional/EditorLoadingTest.php
+++ b/core/modules/editor/tests/src/Functional/EditorLoadingTest.php
@@ -313,7 +313,7 @@ protected function getThingsToCheck($field_name, $type = 'textarea') {
       // Editor.module's JS settings present.
       isset($settings['editor']),
       // Editor.module's JS present.
-      strpos($this->getSession()->getPage()->getContent(), drupal_get_path('module', 'editor') . '/js/editor.js') !== FALSE,
+      strpos($this->getSession()->getPage()->getContent(), $this->getModulePath('editor') . '/js/editor.js') !== FALSE,
       // Body field.
       $this->xpath('//' . $type . '[@id="edit-' . $field_name . '-0-value"]'),
     ];
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index e67ad4edcf27d71248555ae07976e8334316391f..dd67e8f2b4ea6bcab8ba5bcb8ef7ead0700a52ce 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -145,7 +145,7 @@ function locale_translate_batch_build(array $files, array $options) {
   ];
   if (count($files)) {
     $batch_builder = (new BatchBuilder())
-      ->setFile(drupal_get_path('module', 'locale') . '/locale.bulk.inc')
+      ->setFile(\Drupal::service('extension.list.module')->getPath('locale') . '/locale.bulk.inc')
       ->setTitle(t('Importing interface translations'))
       ->setErrorMessage(t('Error importing interface translations'));
     foreach ($files as $file) {
@@ -567,7 +567,7 @@ function locale_config_batch_update_components(array $options, array $langcodes
 function locale_config_batch_build(array $names, array $langcodes, array $options = []) {
   $options += ['finish_feedback' => TRUE];
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'locale') . '/locale.bulk.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('locale') . '/locale.bulk.inc')
     ->setTitle(t('Updating configuration translations'))
     ->setInitMessage(t('Starting configuration update'))
     ->setErrorMessage(t('Error updating configuration translations'));
diff --git a/core/modules/locale/locale.compare.inc b/core/modules/locale/locale.compare.inc
index 7321b55159cc9e28377faff152d608ca46fedd71..1c81cc87f9a4ac92f4ad4f96d0dd7e89754fdb1e 100644
--- a/core/modules/locale/locale.compare.inc
+++ b/core/modules/locale/locale.compare.inc
@@ -240,7 +240,7 @@ function locale_translation_batch_status_build($projects = [], $langcodes = [])
   $operations = _locale_translation_batch_status_operations($projects, $langcodes, $options);
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'locale') . '/locale.batch.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('locale') . '/locale.batch.inc')
     ->setTitle(t('Checking translations'))
     ->setErrorMessage(t('Error checking translation updates.'))
     ->setFinishCallback('locale_translation_batch_status_finished');
diff --git a/core/modules/locale/locale.fetch.inc b/core/modules/locale/locale.fetch.inc
index ecaa48c47f034e99730196324f1219772bafea0b..89114ccc21879f4b70288c6b239b86168ff46c6f 100644
--- a/core/modules/locale/locale.fetch.inc
+++ b/core/modules/locale/locale.fetch.inc
@@ -36,7 +36,7 @@ function locale_translation_batch_update_build($projects = [], $langcodes = [],
   $status_options['finish_feedback'] = FALSE;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'locale') . '/locale.batch.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('locale') . '/locale.batch.inc')
     ->setTitle(t('Updating translations'))
     ->setErrorMessage(t('Error importing translation files'))
     ->setFinishCallback('locale_translation_batch_fetch_finished');
@@ -72,7 +72,7 @@ function locale_translation_batch_fetch_build($projects = [], $langcodes = [], $
   $batch_builder = (new BatchBuilder())
     ->setTitle(t('Updating translations.'))
     ->setErrorMessage(t('Error importing translation files'))
-    ->setFile(drupal_get_path('module', 'locale') . '/locale.batch.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('locale') . '/locale.batch.inc')
     ->setFinishCallback('locale_translation_batch_fetch_finished');
   $operations = _locale_translation_fetch_operations($projects, $langcodes, $options);
   array_walk($operations, function ($operation) use ($batch_builder) {
diff --git a/core/modules/media/media.install b/core/modules/media/media.install
index f9fddb2511c9d5754159dd7a34029156876f1c93..a2e4751f2cad3735e6b7020a8c60d0cf3d5a06ed 100644
--- a/core/modules/media/media.install
+++ b/core/modules/media/media.install
@@ -19,7 +19,7 @@
  * Implements hook_install().
  */
 function media_install() {
-  $source = drupal_get_path('module', 'media') . '/images/icons';
+  $source = \Drupal::service('extension.list.module')->getPath('media') . '/images/icons';
   $destination = \Drupal::config('media.settings')->get('icon_base_uri');
   /** @var \Drupal\Core\File\FileSystemInterface $file_system */
   $file_system = \Drupal::service('file_system');
diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaDisplayTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaDisplayTest.php
index 95b4135e9b6020a0364ef3c53798d63af3d5e312..fbe516239e2752a7381d10c696eecb11b3733aac 100644
--- a/core/modules/media/tests/src/FunctionalJavascript/MediaDisplayTest.php
+++ b/core/modules/media/tests/src/FunctionalJavascript/MediaDisplayTest.php
@@ -29,7 +29,7 @@ protected function setUp(): void {
     parent::setUp();
 
     // Install the optional configs from the standard profile.
-    $extension_path = drupal_get_path('profile', 'standard');
+    $extension_path = $this->container->get('extension.list.profile')->getPath('standard');
     $optional_install_path = $extension_path . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
     $storage = new FileStorage($optional_install_path);
     $this->container->get('config.installer')->installOptionalConfig($storage, '');
diff --git a/core/modules/media/tests/src/Traits/OEmbedTestTrait.php b/core/modules/media/tests/src/Traits/OEmbedTestTrait.php
index 555540f42d19b32813295a4af556953d3e9a248c..7f44db1eab4380312686d8397c89b68c4a03c353 100644
--- a/core/modules/media/tests/src/Traits/OEmbedTestTrait.php
+++ b/core/modules/media/tests/src/Traits/OEmbedTestTrait.php
@@ -17,7 +17,7 @@ trait OEmbedTestTrait {
    * @return string
    */
   protected function getFixturesDirectory() {
-    return drupal_get_path('module', 'media') . '/tests/fixtures/oembed';
+    return \Drupal::service('extension.list.module')->getPath('media') . '/tests/fixtures/oembed';
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php
index 8c47cb54b2adbdeb1524910b78e44f50ca1e3158..f0183917f1abb190762fc855c6a4391d59cb393f 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/CredentialFormTest.php
@@ -27,7 +27,7 @@ class CredentialFormTest extends MigrateUpgradeTestBase {
    * @dataProvider providerCredentialForm
    */
   public function testCredentialFrom($path_to_database) {
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . $path_to_database);
+    $this->loadFixture($this->getModulePath('migrate_drupal') . $path_to_database);
     $session = $this->assertSession();
 
     // Get valid credentials.
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php
index d51a231af3a121ad5fd12cb0543b7a3a86c11ae3..9fa261d2a31c88adb566a81e78d31f4361ff6e82 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/SourceProviderTest.php
@@ -24,7 +24,7 @@ class SourceProviderTest extends MigrateUpgradeTestBase {
    * @dataProvider providerSourceProvider
    */
   public function testSourceProvider($path_to_database) {
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . $path_to_database);
+    $this->loadFixture($this->getModulePath('migrate_drupal') . $path_to_database);
 
     $session = $this->assertSession();
 
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php
index bc134d33e9ff275795de1d839f8e8bf4e5436a25..bf75e753ebb3e16eec12628529311bfd8beec3c0 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php
@@ -33,7 +33,7 @@ class IdConflictTest extends MigrateUpgradeExecuteTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal6.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php
index a3f04b57b321a4db2bff4206c204020bce71dcde..989f0963ee0a015d6314972a55ed9e8e735f78f3 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MultilingualReviewPageTest.php
@@ -41,7 +41,7 @@ class MultilingualReviewPageTest extends MultilingualReviewPageTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal6.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NoMultilingualReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NoMultilingualReviewPageTest.php
index 57aa25e66bbd34e786ef5c286f8cde2eb0b2bf9d..b97373f5e3b08986638b1647c2465e707cb746c1 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NoMultilingualReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NoMultilingualReviewPageTest.php
@@ -38,7 +38,7 @@ class NoMultilingualReviewPageTest extends NoMultilingualReviewPageTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal6.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php
index 908fa70d6df1de3c1f15ec940388b563ba0dfa6b..c751ff5531fdcf05884f99c81c22783af0ef6832 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/NodeClassicTest.php
@@ -40,7 +40,7 @@ class NodeClassicTest extends MigrateUpgradeExecuteTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal6.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
index 77e4d3042d835d977deea6cc6f20da79e4129ba3..9a92f8b6781a703f489fbd546167256aaaf78cb6 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
@@ -52,7 +52,7 @@ protected function setUp(): void {
       ->getStorage('node');
     $this->nodeStorage->delete($this->nodeStorage->loadMultiple());
 
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal6.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/DoubleSlashTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/DoubleSlashTest.php
index d17fc5336e274345308ae91ae16d5c2e5c16a5b9..330f46cc8422c576e51a9bd33c66a1bf39f7e923 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/DoubleSlashTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/DoubleSlashTest.php
@@ -36,7 +36,7 @@ class DoubleSlashTest extends MigrateUpgradeExecuteTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
+    $this->loadFixture(\Drupal::service('extension.list.module')->getPath('migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/FilePathTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/FilePathTest.php
index aa56cb19feb5b64baa999ff57bfaaaa6d96f7519..db4848146239102ea9b1d3c1d331121c207f75ae 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/FilePathTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/FilePathTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\migrate_drupal_ui\Functional\d7;
 
 use Drupal\Core\File\FileSystemInterface;
+use Drupal\Tests\ExtensionListTestTrait;
 use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase;
 
 /**
@@ -17,6 +18,8 @@
  */
 class FilePathTest extends MigrateUpgradeTestBase {
 
+  use ExtensionListTestTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -67,7 +70,7 @@ class FilePathTest extends MigrateUpgradeTestBase {
   protected function setUp(): void {
     parent::setUp();
     $this->fs = \Drupal::service('file_system');
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/IdConflictTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/IdConflictTest.php
index 597f998c4da7c78f63d79fb5f37fca8bdeb71cf3..0b0dc58ec9bbcdaa89b5bab1ebb880a6a736229d 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/IdConflictTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/IdConflictTest.php
@@ -33,7 +33,7 @@ class IdConflictTest extends MigrateUpgradeExecuteTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php
index 9b3208e2d462186d44a901f65ec536375888e664..13df45943b2c33b3057571e8c66cacbf906ad790 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MultilingualReviewPageTest.php
@@ -40,7 +40,7 @@ class MultilingualReviewPageTest extends MultilingualReviewPageTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/NoMultilingualReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/NoMultilingualReviewPageTest.php
index fc95f57e74a5eca7ce4922049b4e9b1bfdfe2753..35c0e3500e66e987d24e8c6cb613950a116814c6 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/NoMultilingualReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/NoMultilingualReviewPageTest.php
@@ -36,7 +36,7 @@ class NoMultilingualReviewPageTest extends NoMultilingualReviewPageTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
   /**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
index c9495412e95c6f6b2fdb4e8a5e61f53847a28eb1..58cb7b79c6cf7a36fbfc4080d799abfffa6cd911 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
@@ -53,7 +53,7 @@ protected function setUp(): void {
       ->getStorage('node');
     $this->nodeStorage->delete($this->nodeStorage->loadMultiple());
 
-    $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php');
+    $this->loadFixture($this->getModulePath('migrate_drupal') . '/tests/fixtures/drupal7.php');
   }
 
   /**
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index a0588584461ebcc34f5f045cd9a79f915ad63317..ff5f8331907b9431146d28e10e1609e8f1f738e4 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -38,7 +38,7 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load
     $batch_builder = (new BatchBuilder())
       // The operations do not live in the .module file, so we need to
       // tell the batch engine which file to load before calling them.
-      ->setFile(drupal_get_path('module', 'node') . '/node.admin.inc')
+      ->setFile(\Drupal::service('extension.list.module')->getPath('node') . '/node.admin.inc')
       ->addOperation('_node_mass_update_batch_process', [$nodes, $updates, $langcode, $load, $revisions])
       ->setFinishCallback('_node_mass_update_batch_finished')
       ->setTitle(t('Processing'))
diff --git a/core/modules/quickedit/quickedit.module b/core/modules/quickedit/quickedit.module
index 38298d562ee03ba58971ffbb67d07f7ea7f72cc2..b3b8eef894a4181ff3d3999dc2f395d86493dfd0 100644
--- a/core/modules/quickedit/quickedit.module
+++ b/core/modules/quickedit/quickedit.module
@@ -79,8 +79,10 @@ function quickedit_library_info_alter(&$libraries, $extension) {
 
     // First let the base theme modify the library, then the actual theme.
     $alter_library = function (&$library, $theme) use (&$alter_library) {
-      if (!empty($theme) && $theme_path = drupal_get_path('theme', $theme)) {
-        $info = \Drupal::service('extension.list.theme')->getExtensionInfo($theme);
+      /** @var \Drupal\Core\Extension\ThemeExtensionList $theme_list */
+      $theme_list = \Drupal::service('extension.list.theme');
+      if (!empty($theme) && $theme_path = $theme_list->getPath($theme)) {
+        $info = $theme_list->getExtensionInfo($theme);
         // Recurse to process base theme(s) first.
         if (isset($info['base theme'])) {
           $alter_library($library, $info['base theme']);
diff --git a/core/modules/settings_tray/settings_tray.module b/core/modules/settings_tray/settings_tray.module
index 18c77c7a7339cfcdbeb159d12b50f4aae7585693..2004d943bf4503f8eddbe188dd81d00632185b90 100644
--- a/core/modules/settings_tray/settings_tray.module
+++ b/core/modules/settings_tray/settings_tray.module
@@ -180,7 +180,7 @@ function settings_tray_block_alter(&$definitions) {
 function settings_tray_css_alter(&$css, AttachedAssetsInterface $assets) {
   // @todo Remove once conditional ordering is introduced in
   //   https://www.drupal.org/node/1945262.
-  $path = drupal_get_path('module', 'settings_tray') . '/css/settings_tray.theme.css';
+  $path = \Drupal::service('extension.list.module')->getPath('settings_tray') . '/css/settings_tray.theme.css';
   if (isset($css[$path])) {
     // Use 200 to come after CSS_AGGREGATE_THEME.
     $css[$path]['group'] = 200;
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index 6e3fea44f7136d54bb725cbb7740271a69840d7e..40066c611f25c7cf38ac628400793e5a8dc91ab7 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -40,7 +40,7 @@ function statistics_help($route_name, RouteMatchInterface $route_match) {
 function statistics_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) {
   if (!$node->isNew() && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) {
     $build['#attached']['library'][] = 'statistics/drupal.statistics';
-    $settings = ['data' => ['nid' => $node->id()], 'url' => \Drupal::request()->getBasePath() . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'];
+    $settings = ['data' => ['nid' => $node->id()], 'url' => \Drupal::request()->getBasePath() . '/' . \Drupal::service('extension.list.module')->getPath('statistics') . '/statistics.php'];
     $build['#attached']['drupalSettings']['statistics'] = $settings;
   }
 }
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php b/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php
index 7807cc94c8e16ece6cf3b02f81ce45df9d156152..0b9418ab14abd320b077104ebc60dd7191abea9e 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php
@@ -88,7 +88,7 @@ public function testStatisticsSettings() {
     $nid = $this->testNode->id();
     $post = ['nid' => $nid];
     global $base_url;
-    $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
+    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
     $this->client->post($stats_path, ['form_params' => $post]);
 
     // Hit the node again (the counter is incremented after the hit, so
@@ -124,7 +124,7 @@ public function testDeleteNode() {
     $nid = $this->testNode->id();
     $post = ['nid' => $nid];
     global $base_url;
-    $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
+    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
     $this->client->post($stats_path, ['form_params' => $post]);
 
     $connection = Database::getConnection();
@@ -159,7 +159,7 @@ public function testExpiredLogs() {
     $nid = $this->testNode->id();
     $post = ['nid' => $nid];
     global $base_url;
-    $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
+    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
     $this->client->post($stats_path, ['form_params' => $post]);
     $this->drupalGet('node/' . $this->testNode->id());
     $this->client->post($stats_path, ['form_params' => $post]);
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php b/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php
index 0ce939efba7f0aeb4ab06607a1d943a3b45d8120..77dd94636a45cb0e33056bfbf1ed4ae43fe979e3 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php
@@ -99,7 +99,7 @@ protected function setUp(): void {
    */
   public function testLogging() {
     $path = 'node/' . $this->node->id();
-    $module_path = drupal_get_path('module', 'statistics');
+    $module_path = $this->getModulePath('statistics');
     $stats_path = base_path() . $module_path . '/statistics.php';
     $lib_path = base_path() . $module_path . '/statistics.js';
     $expected_library = '/<script src=".*?' . preg_quote($lib_path, '/.') . '.*?">/is';
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
index 7bdaa303b73b47c58ed44cb06ea357ad38fa439c..7138d73bd7b548e67442030fda5cc0ef305e5566 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php
@@ -35,7 +35,7 @@ public function testPopularContentBlock() {
     $post = http_build_query(['nid' => $nid]);
     $headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
     global $base_url;
-    $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
+    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
     $client = \Drupal::httpClient();
     $client->post($stats_path, ['headers' => $headers, 'body' => $post]);
 
diff --git a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php
index d39f37ca6e9a02a1fd6035366fd577cabdc6317d..160650bc61446687cddaa0269d1d1f4576e85983 100644
--- a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php
+++ b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php
@@ -51,7 +51,7 @@ public function testStatisticsTokenReplacement() {
     $post = http_build_query(['nid' => $nid]);
     $headers = ['Content-Type' => 'application/x-www-form-urlencoded'];
     global $base_url;
-    $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
+    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
     $client = \Drupal::httpClient();
     $client->post($stats_path, ['headers' => $headers, 'body' => $post]);
     /** @var \Drupal\statistics\StatisticsViewsResult $statistics */
diff --git a/core/modules/statistics/tests/src/Functional/Views/IntegrationTest.php b/core/modules/statistics/tests/src/Functional/Views/IntegrationTest.php
index 3c348c9ca12b07d22545e50c5dc7cde4d226691d..6ff40ce288e1a56478cd0dfa3ee117f4a317a08a 100644
--- a/core/modules/statistics/tests/src/Functional/Views/IntegrationTest.php
+++ b/core/modules/statistics/tests/src/Functional/Views/IntegrationTest.php
@@ -81,7 +81,7 @@ public function testNodeCounterIntegration() {
     // Manually calling statistics.php, simulating ajax behavior.
     // @see \Drupal\statistics\Tests\StatisticsLoggingTest::testLogging().
     global $base_url;
-    $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php';
+    $stats_path = $base_url . '/' . $this->getModulePath('statistics') . '/statistics.php';
     $client = $this->getHttpClient();
     $client->post($stats_path, ['form_params' => ['nid' => $this->node->id()]]);
     $this->drupalGet('test_statistics_integration');
diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php
index 03e4a4a33c3e6bf957d5f4008e962db501690273..8fa152625f2a2c80349b7e6b615731f5cf1da2b1 100644
--- a/core/modules/system/src/Form/ThemeSettingsForm.php
+++ b/core/modules/system/src/Form/ThemeSettingsForm.php
@@ -307,7 +307,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
           $local_file = strtr($original_path, ['public:/' => PublicStream::basePath()]);
         }
         elseif ($theme) {
-          $local_file = drupal_get_path('theme', $theme) . '/' . $default;
+          $local_file = $this->themeHandler->getTheme($theme)->getPath() . '/' . $default;
         }
         else {
           $local_file = $this->themeManager->getActiveTheme()->getPath() . '/' . $default;
@@ -355,7 +355,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
       // Process the theme and all its base themes.
       foreach ($theme_keys as $theme) {
         // Include the theme-settings.php file.
-        $theme_path = drupal_get_path('theme', $theme);
+        $theme_path = $this->themeHandler->getTheme($theme)->getPath();
         $theme_settings_file = $theme_path . '/theme-settings.php';
         $theme_file = $theme_path . '/' . $theme . '.theme';
         $filenames = [$theme_settings_file, $theme_file];
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 9c577d0f98e1d3368d35508ddeef3cd812af2070..40fa1037ec75ad9b2addfdd3c8fb310df3a58481 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -288,7 +288,7 @@ function template_preprocess_system_themes_page(&$variables) {
       else {
         $current_theme['screenshot'] = [
           '#theme' => 'image',
-          '#uri' => drupal_get_path('module', 'system') . '/images/no_screenshot.png',
+          '#uri' => \Drupal::service('extension.list.module')->getPath('system') . '/images/no_screenshot.png',
           '#alt' => t('No screenshot'),
           '#title' => t('No screenshot'),
           '#attributes' => new Attribute(['class' => ['no-screenshot']]),
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index f6481d8ff67b62ebd2671faed5d9e9d945802d8b..8f4116503e27a07f517ae75b9143187318fd2b39 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -432,7 +432,7 @@ function template_preprocess_entity_add_list(&$variables) {
  * Example (update_manager_install_form_submit()):
  * @code
  *  system_authorized_init('update_authorize_run_install',
- *    drupal_get_path('module', 'update') . '/update.authorize.inc',
+ *    \Drupal::service('extension.list.module')->getPath('update') . '/update.authorize.inc',
  *    $arguments, t('Update manager'));
  *  $form_state->setRedirectUrl(system_authorized_get_url());
  * @endcode
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index ba5923df2fa9f5812ad8900619c0edacb476667d..6dd80f61cffc8cf01a372c109f758226c60851b3 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -22,7 +22,7 @@ function _batch_test_nested_drupal_form_submit_callback($value) {
  */
 function _batch_test_batch_0() {
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_0');
   return $batch_builder->toArray() + ['batch_test_id' => 'batch_0'];
 }
@@ -38,7 +38,7 @@ function _batch_test_batch_1() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_1');
 
   for ($i = 1; $i <= $total; $i++) {
@@ -59,7 +59,7 @@ function _batch_test_batch_2() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->addOperation('_batch_test_callback_2', [1, $total, $sleep])
     ->setFinishCallback('_batch_test_finished_2');
 
@@ -81,7 +81,7 @@ function _batch_test_batch_3() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_3');
   for ($i = 1; $i <= round($total / 2); $i++) {
     $batch_builder->addOperation('_batch_test_callback_1', [$i, $sleep]);
@@ -109,7 +109,7 @@ function _batch_test_batch_4() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_4');
   for ($i = 1; $i <= round($total / 2); $i++) {
     $batch_builder->addOperation('_batch_test_callback_1', [$i, $sleep]);
@@ -133,7 +133,7 @@ function _batch_test_batch_5() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_5');
   for ($i = 1; $i <= $total; $i++) {
     $batch_builder->addOperation('_batch_test_callback_5', [$i, $sleep]);
@@ -153,7 +153,7 @@ function _batch_test_batch_6() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_6');
   for ($i = 1; $i <= $total; $i++) {
     $batch_builder->addOperation('_batch_test_callback_6', [$i, $sleep]);
@@ -177,7 +177,7 @@ function _batch_test_batch_7() {
   $sleep = (1000000 / $total) * 2;
 
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('batch_test') . '/batch_test.callbacks.inc')
     ->setFinishCallback('_batch_test_finished_7');
   for ($i = 1; $i <= $total / 2; $i++) {
     $batch_builder->addOperation('_batch_test_callback_7', [$i, $sleep]);
diff --git a/core/modules/system/tests/modules/common_test/common_test.module b/core/modules/system/tests/modules/common_test/common_test.module
index c8b496db0487baf54743c6e67ddd4e5c412d5291..aa6dc02af799637a586da24c0edf314756e70e99 100644
--- a/core/modules/system/tests/modules/common_test/common_test.module
+++ b/core/modules/system/tests/modules/common_test/common_test.module
@@ -252,7 +252,7 @@ function common_test_page_attachments_alter(array &$page) {
  */
 function common_test_js_alter(&$javascript, AttachedAssetsInterface $assets) {
   // Attach alter.js above tableselect.js.
-  $alterjs = drupal_get_path('module', 'common_test') . '/alter.js';
+  $alterjs = \Drupal::service('extension.list.module')->getPath('common_test') . '/alter.js';
   if (array_key_exists($alterjs, $javascript) && array_key_exists('core/misc/tableselect.js', $javascript)) {
     $javascript[$alterjs]['weight'] = $javascript['core/misc/tableselect.js']['weight'] - 1;
   }
diff --git a/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php
index bb98a59c97499f5fbc4646e5e4246149392a3f0c..1fbba00a1475cd689c5d1f18a21b3e645a1316d5 100644
--- a/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php
+++ b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php
@@ -3,6 +3,7 @@
 namespace Drupal\common_test\Controller;
 
 use Drupal\Component\Utility\Html;
+use Drupal\Core\Extension\ExtensionList;
 use Drupal\Core\Url;
 use Symfony\Component\HttpFoundation\Response;
 
@@ -61,15 +62,17 @@ public function typeLinkActiveClass() {
    *   An empty string.
    */
   public function jsAndCssQuerystring() {
+    $module_extension_list = \Drupal::service('extension.list.module');
+    assert($module_extension_list instanceof ExtensionList);
     $attached = [
       '#attached' => [
         'library' => [
           'node/drupal.node',
         ],
         'css' => [
-          drupal_get_path('module', 'node') . '/css/node.admin.css' => [],
+          $module_extension_list->getPath('node') . '/css/node.admin.css' => [],
           // A relative URI may have a query string.
-          '/' . drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&arg2=value2' => [],
+          '/' . $module_extension_list->getPath('node') . '/node-fake.css?arg1=value1&arg2=value2' => [],
         ],
       ],
     ];
diff --git a/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php b/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php
index bfdb7287aaf37f5377bf9970397272d03d78c690..76904ee56da8157ce425adbea627e8032779bd2c 100644
--- a/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php
+++ b/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php
@@ -77,7 +77,7 @@ public function assertModuleTablesDoNotExist($module) {
    *   The name of the module.
    */
   public function assertModuleConfig($module) {
-    $module_config_dir = drupal_get_path('module', $module) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
+    $module_config_dir = $this->getModulePath($module) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
     if (!is_dir($module_config_dir)) {
       return;
     }
diff --git a/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php b/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php
index 1751c42801b50f68b7007c0ee09844ce21aa04ac..59658be618bb6865f6593f1a38b35d2171d965a2 100644
--- a/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php
+++ b/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php
@@ -33,19 +33,19 @@ public function testErrorHandler() {
       '%type' => 'Notice',
       '@message' => 'Object of class stdClass could not be converted to int',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
     $error_warning = [
       '%type' => 'Warning',
       '@message' => 'var_export does not handle circular references',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
     $error_user_notice = [
       '%type' => 'User warning',
       '@message' => 'Drupal & awesome',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
 
     // Set error reporting to display verbose notices.
@@ -101,21 +101,21 @@ public function testExceptionHandler() {
       '@message' => 'Drupal & awesome',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->triggerException()',
       '%line' => 56,
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
     $error_pdo_exception = [
       '%type' => 'DatabaseExceptionWrapper',
       '@message' => 'SELECT "b".* FROM {bananas_are_awesome} "b"',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->triggerPDOException()',
       '%line' => 64,
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
     $error_renderer_exception = [
       '%type' => 'Exception',
       '@message' => 'This is an exception that occurs during rendering',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->Drupal\error_test\Controller\{closure}()',
       '%line' => 82,
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => $this->getModulePath('error_test') . '/error_test.module',
     ];
 
     $this->drupalGet('error-test/trigger-exception');
diff --git a/core/modules/system/tests/src/Functional/System/HtaccessTest.php b/core/modules/system/tests/src/Functional/System/HtaccessTest.php
index c2b7f051cb3a7909aaf08aebea2127a63481b127..092f57ac7020d4907d3da7ba8cf6b27e71063d60 100644
--- a/core/modules/system/tests/src/Functional/System/HtaccessTest.php
+++ b/core/modules/system/tests/src/Functional/System/HtaccessTest.php
@@ -31,7 +31,7 @@ class HtaccessTest extends BrowserTestBase {
    *   for example, 200 or 403.
    */
   protected function getProtectedFiles() {
-    $path = drupal_get_path('module', 'system') . '/tests/fixtures/HtaccessTest';
+    $path = $this->getModulePath('system') . '/tests/fixtures/HtaccessTest';
 
     // Tests the FilesMatch directive which denies access to certain file
     // extensions.
diff --git a/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php b/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php
index 4900c08c9d8f3258a3aa159ec32d345fa3a403b6..eab06c75f6191430a7ae14587e9304adce80298e 100644
--- a/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php
+++ b/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php
@@ -64,8 +64,8 @@ public function testStylesheets() {
       ->set('default', 'test_subtheme')
       ->save();
 
-    $base = drupal_get_path('theme', 'test_basetheme');
-    $sub = drupal_get_path('theme', 'test_subtheme') . '/css';
+    $base = $this->getThemePath('test_basetheme');
+    $sub = $this->getThemePath('test_subtheme') . '/css';
 
     // All removals are expected to be based on a file's path and name and
     // should work nevertheless.
diff --git a/core/modules/system/tests/src/Functional/Theme/TwigDebugMarkupTest.php b/core/modules/system/tests/src/Functional/Theme/TwigDebugMarkupTest.php
index bff40691addaca6ffa50ea9dd1de55eedbf719d8..311b762b45d6bad5b7b5652a16e96f6529862778 100644
--- a/core/modules/system/tests/src/Functional/Theme/TwigDebugMarkupTest.php
+++ b/core/modules/system/tests/src/Functional/Theme/TwigDebugMarkupTest.php
@@ -43,8 +43,8 @@ public function testTwigDebugMarkup() {
 
     $cache = $this->container->get('theme.registry')->get();
     // Create array of Twig templates.
-    $templates = drupal_find_theme_templates($cache, $extension, drupal_get_path('theme', 'test_theme'));
-    $templates += drupal_find_theme_templates($cache, $extension, drupal_get_path('module', 'node'));
+    $templates = drupal_find_theme_templates($cache, $extension, $this->getThemePath('test_theme'));
+    $templates += drupal_find_theme_templates($cache, $extension, $this->getModulePath('node'));
 
     // Create a node and test different features of the debug markup.
     $node = $this->drupalCreateNode();
diff --git a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
index 9d588a23e17116e6994e8f5b9f50284829f26873..a88768a9271da1888b06ebd9ff88abe61ba8077a 100644
--- a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
+++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Core\Extension\MissingDependencyException;
 use Drupal\Core\Extension\ModuleUninstallValidatorException;
+use Drupal\Core\Extension\ProfileExtensionList;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -162,12 +163,14 @@ public function testUninstallProfileDependency() {
     $dependency = 'dblog';
     $non_dependency = 'ban';
     $this->setInstallProfile($profile);
-    // Prime the drupal_get_filename() static cache with the location of the
-    // testing_install_profile_dependencies profile as it is not the currently
-    // active profile and we don't yet have any cached way to retrieve its
-    // location.
+    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname() static
+    // cache with the location of the testing_install_profile_dependencies
+    // profile as it is not the currently active profile and we don't yet have
+    // any cached way to retrieve its location.
     // @todo Remove as part of https://www.drupal.org/node/2186491
-    drupal_get_filename('profile', $profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
+    $profile_list = \Drupal::service('extension.list.profile');
+    assert($profile_list instanceof ProfileExtensionList);
+    $profile_list->setPathname($profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
     $this->enableModules(['module_test', $profile]);
 
     $data = \Drupal::service('extension.list.module')->reset()->getList();
@@ -202,14 +205,15 @@ public function testUninstallProfileDependency() {
   public function testProfileAllDependencies() {
     $profile = 'testing_install_profile_all_dependencies';
     $dependencies = ['dblog', 'ban'];
-
     $this->setInstallProfile($profile);
-    // Prime the drupal_get_filename() static cache with the location of the
-    // testing_install_profile_dependencies profile as it is not the currently
-    // active profile and we don't yet have any cached way to retrieve its
-    // location.
+    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname() static
+    // cache with the location of the testing_install_profile_dependencies
+    // profile as it is not the currently active profile and we don't yet have
+    // any cached way to retrieve its location.
     // @todo Remove as part of https://www.drupal.org/node/2186491
-    drupal_get_filename('profile', $profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
+    $profile_list = \Drupal::service('extension.list.profile');
+    assert($profile_list instanceof ProfileExtensionList);
+    $profile_list->setPathname($profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
     $this->enableModules(['module_test', $profile]);
 
     $data = \Drupal::service('extension.list.module')->reset()->getList();
diff --git a/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php b/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php
index 2e762b646fda501b9c6a34b6d20d04b954620e6d..065ff69bea4c475f4fa89343b19a302bc5e50361 100644
--- a/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php
+++ b/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\system\Kernel\Installer;
 
+use Drupal\Core\Extension\ProfileExtensionList;
 use Drupal\KernelTests\KernelTestBase;
 
 /**
@@ -20,11 +21,14 @@ class InstallerDependenciesResolutionTest extends KernelTestBase {
    * Verifies that the exception message in the profile step is correct.
    */
   public function testDependenciesResolution() {
-    // Prime the drupal_get_filename() static cache with the location of the
-    // testing profile as it is not the currently active profile and we don't
-    // yet have any cached way to retrieve its location.
+    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
+    // with the location of the testing profile as it is not the currently
+    // active profile and we don't yet have any cached way to retrieve its
+    // location.
     // @todo Remove as part of https://www.drupal.org/node/2186491
-    drupal_get_filename('profile', 'testing_missing_dependencies', 'core/profiles/testing_missing_dependencies/testing_missing_dependencies.info.yml');
+    $profile_list = \Drupal::service('extension.list.profile');
+    assert($profile_list instanceof ProfileExtensionList);
+    $profile_list->setPathname('testing_missing_dependencies', 'core/profiles/testing_missing_dependencies/testing_missing_dependencies.info.yml');
 
     $info = drupal_verify_profile([
       'parameters' => ['profile' => 'testing_missing_dependencies'],
diff --git a/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php b/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php
index 932790d6b45a82506e4895984cfef654c13f18d1..5a072ea434e6d79fe8baa73212961d95e0901356 100644
--- a/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php
+++ b/core/modules/system/tests/src/Kernel/Theme/ThemeTest.php
@@ -151,7 +151,7 @@ public function testDrupalRenderChildren() {
    */
   public function testFindThemeTemplates() {
     $registry = $this->container->get('theme.registry')->get();
-    $templates = drupal_find_theme_templates($registry, '.html.twig', drupal_get_path('theme', 'test_theme'));
+    $templates = drupal_find_theme_templates($registry, '.html.twig', $this->getThemePath('test_theme'));
     $this->assertEquals('node--1', $templates['node__1']['template'], 'Template node--1.html.twig was found in test_theme.');
   }
 
diff --git a/core/modules/update/src/Form/UpdateManagerUpdate.php b/core/modules/update/src/Form/UpdateManagerUpdate.php
index 61b5d04b62c542906219d7a7b13356ccac4f79ae..5dbd1bfe527c70a9f3784ddc8343a48c8a4b71b8 100644
--- a/core/modules/update/src/Form/UpdateManagerUpdate.php
+++ b/core/modules/update/src/Form/UpdateManagerUpdate.php
@@ -379,7 +379,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       }
     }
     $batch_builder = (new BatchBuilder())
-      ->setFile(drupal_get_path('module', 'update') . '/update.manager.inc')
+      ->setFile($this->moduleHandler->getModule('update')->getPath() . '/update.manager.inc')
       ->setTitle($this->t('Downloading updates'))
       ->setInitMessage($this->t('Preparing to download selected updates'))
       ->setFinishCallback('update_manager_download_batch_finished');
diff --git a/core/modules/update/update.authorize.inc b/core/modules/update/update.authorize.inc
index 86ecda3b89a082a0ea306f544a239e0235a4c2be..13d5906942c157e1f52bc24a5856fdf3b15fc813 100644
--- a/core/modules/update/update.authorize.inc
+++ b/core/modules/update/update.authorize.inc
@@ -38,7 +38,7 @@
  */
 function update_authorize_run_update($filetransfer, $projects) {
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'update') . '/update.authorize.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('update') . '/update.authorize.inc')
     ->setInitMessage(t('Preparing to update your site'))
     ->setFinishCallback('update_authorize_update_batch_finished');
 
@@ -89,7 +89,7 @@ function update_authorize_run_update($filetransfer, $projects) {
 function update_authorize_run_install($filetransfer, $project, $updater_name, $local_url) {
   // @todo Instantiate our Updater to set the human-readable title?
   $batch_builder = (new BatchBuilder())
-    ->setFile(drupal_get_path('module', 'update') . '/update.authorize.inc')
+    ->setFile(\Drupal::service('extension.list.module')->getPath('update') . '/update.authorize.inc')
     ->setInitMessage(t('Preparing to install'))
     ->addOperation('update_authorize_batch_copy_project', [
       $project,
diff --git a/core/modules/views/src/Tests/ViewTestData.php b/core/modules/views/src/Tests/ViewTestData.php
index 6033fcfd33f5917ee798af007d63c4de7dc4d9fe..737f4a237ac775e121df6faa8bc8f884c4d5ff45 100644
--- a/core/modules/views/src/Tests/ViewTestData.php
+++ b/core/modules/views/src/Tests/ViewTestData.php
@@ -34,7 +34,7 @@ public static function createTestViews($class, array $modules) {
       $storage = \Drupal::entityTypeManager()->getStorage('view');
       $module_handler = \Drupal::moduleHandler();
       foreach ($modules as $module) {
-        $config_dir = drupal_get_path('module', $module) . '/test_views';
+        $config_dir = \Drupal::service('extension.list.module')->getPath($module) . '/test_views';
         if (!is_dir($config_dir) || !$module_handler->moduleExists($module)) {
           continue;
         }
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
index 2246ba1ed5a2dd3fdbdb4f508ffda9d69c7c1da8..2c4b507eac829b4b1c7624f420e8d5e6e309a97b 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigUpdaterTest.php
@@ -48,7 +48,7 @@ protected function setUp($import_test_views = TRUE): void {
   protected function loadTestView($view_id) {
     // We just instantiate the test view from the raw configuration, as it may
     // not be possible to save it, due to its faulty schema.
-    $config_dir = drupal_get_path('module', 'views') . '/tests/fixtures/update';
+    $config_dir = $this->getModulePath('views') . '/tests/fixtures/update';
     $file_storage = new FileStorage($config_dir);
     $values = $file_storage->read($view_id);
     /** @var \Drupal\views\ViewEntityInterface $test_view */
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index f04bd56338fc2b2739739f3155daf6f47e194e83..9e03548ee2e338516d2865f50e08ce136e720d0b 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -172,7 +172,7 @@ function views_theme($existing, $type, $theme, $path) {
       ];
 
       // We always use the module directory as base dir.
-      $module_dir = drupal_get_path('module', $def['provider']);
+      $module_dir = \Drupal::service('extension.list.module')->getPath($def['provider']);
       $hooks[$def['theme']]['path'] = $module_dir;
 
       // For the views module we ensure views.theme.inc is included.
diff --git a/core/profiles/demo_umami/tests/src/Functional/DemoUmamiProfileTest.php b/core/profiles/demo_umami/tests/src/Functional/DemoUmamiProfileTest.php
index 31f19889e23659e7333be49cefa244a4352c342f..be483fd9c03a2de58a2a59a4cd58590b6e3e7e2b 100644
--- a/core/profiles/demo_umami/tests/src/Functional/DemoUmamiProfileTest.php
+++ b/core/profiles/demo_umami/tests/src/Functional/DemoUmamiProfileTest.php
@@ -52,10 +52,10 @@ public function testConfig() {
     // the cache layer.
     $active_config_storage = $this->container->get('config.storage');
 
-    $default_config_storage = new FileStorage(drupal_get_path('profile', 'demo_umami') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
+    $default_config_storage = new FileStorage($this->container->get('extension.list.profile')->getPath('demo_umami') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
     $this->assertDefaultConfig($default_config_storage, $active_config_storage);
 
-    $default_config_storage = new FileStorage(drupal_get_path('profile', 'demo_umami') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
+    $default_config_storage = new FileStorage($this->container->get('extension.list.profile')->getPath('demo_umami') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
     $this->assertDefaultConfig($default_config_storage, $active_config_storage);
   }
 
diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseUserAgentTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseUserAgentTest.php
index 42f462d20c169b0c200a4bd84fa468e6cb236db2..744c29ad5680d607e5dff724ee35e73480263b15 100644
--- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseUserAgentTest.php
+++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseUserAgentTest.php
@@ -28,7 +28,7 @@ class BrowserTestBaseUserAgentTest extends BrowserTestBase {
    */
   public function testUserAgentValidation() {
     $assert_session = $this->assertSession();
-    $system_path = $this->buildUrl(drupal_get_path('module', 'system'));
+    $system_path = $this->buildUrl(\Drupal::service('extension.list.module')->getPath('system'));
     $http_path = $system_path . '/tests/http.php/user/login';
     $https_path = $system_path . '/tests/https.php/user/login';
     // Generate a valid simpletest User-Agent to pass validation.
diff --git a/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php b/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php
index 6456734286341089726c1fbec1f1c96954f3ae31..01a44fda3b91c00f666d48acb537ca170804746f 100644
--- a/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php
+++ b/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php
@@ -79,7 +79,7 @@ protected function assertExtensionConfig(string $name, string $type) {
     // this for all tests in case optional configuration depends on it.
     $this->installConfig(['system', 'user']);
 
-    $extension_path = drupal_get_path($type, $name) . '/';
+    $extension_path = \Drupal::service('extension.path.resolver')->getPath($type, $name) . '/';
     $extension_config_storage = new FileStorage($extension_path . InstallStorage::CONFIG_INSTALL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION);
     $optional_config_storage = new FileStorage($extension_path . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION);
 
diff --git a/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php b/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..91f2cac5256f2189ee43c0c737c4f9007e6526e4
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Bootstrap;
+
+use Drupal\Core\Extension\Exception\UnknownExtensionException;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests that extension path resolver works correctly.
+ *
+ * @coversDefaultClass \Drupal\Core\Extension\ExtensionPathResolver
+ *
+ * @group Bootstrap
+ */
+class ExtensionPathResolverTest extends KernelTestBase {
+
+  /**
+   * @covers ::getPathname
+   */
+  public function testExtensionPathResolving(): void {
+    // Retrieving the location of a module.
+    $this->assertSame('core/modules/system/system.info.yml', \Drupal::service('extension.list.module')
+      ->getPathname('system'));
+
+    // Retrieving the location of a theme.
+    \Drupal::service('theme_installer')->install(['stark']);
+    $this->assertSame('core/themes/stark/stark.info.yml', \Drupal::service('extension.list.theme')
+      ->getPathname('stark'));
+
+    // Retrieving the location of a theme engine.
+    $this->assertSame('core/themes/engines/twig/twig.info.yml', \Drupal::service('extension.list.theme_engine')
+      ->getPathname('twig'));
+
+    // Retrieving the location of a profile. Profiles are a special case with
+    // a fixed location and naming.
+    $this->assertSame('core/profiles/testing/testing.info.yml', \Drupal::service('extension.list.profile')
+      ->getPathname('testing'));
+  }
+
+  /**
+   * @covers ::getPath
+   */
+  public function testExtensionPathResolvingPath(): void {
+    $this->assertSame('core/modules/system/tests/modules/driver_test', \Drupal::service('extension.list.module')
+      ->getPath('driver_test'));
+  }
+
+  /**
+   * @covers ::getPathname
+   */
+  public function testExtensionPathResolvingWithNonExistingModule(): void {
+    $this->expectException(UnknownExtensionException::class);
+    $this->expectExceptionMessage('The module there_is_a_module_for_that does not exist.');
+    $this->assertNull(\Drupal::service('extension.list.module')
+      ->getPathname('there_is_a_module_for_that'), 'Searching for an item that does not exist returns NULL.');
+  }
+
+  /**
+   * @covers ::getPathname
+   */
+  public function testExtensionPathResolvingWithNonExistingTheme(): void {
+    $this->expectException(UnknownExtensionException::class);
+    $this->expectExceptionMessage('The theme there_is_a_theme_for_you does not exist.');
+    $this->assertNull(\Drupal::service('extension.list.theme')
+      ->getPathname('there_is_a_theme_for_you'), 'Searching for an item that does not exist returns NULL.');
+  }
+
+  /**
+   * @covers ::getPathname
+   */
+  public function testExtensionPathResolvingWithNonExistingProfile(): void {
+    $this->expectException(UnknownExtensionException::class);
+    $this->expectExceptionMessage('The profile there_is_an_install_profile_for_you does not exist.');
+    $this->assertNull(\Drupal::service('extension.list.profile')
+      ->getPathname('there_is_an_install_profile_for_you'), 'Searching for an item that does not exist returns NULL.');
+  }
+
+  /**
+   * @covers ::getPathname
+   */
+  public function testExtensionPathResolvingWithNonExistingThemeEngine(): void {
+    $this->expectException(UnknownExtensionException::class);
+    $this->expectExceptionMessage('The theme_engine there_is_an_theme_engine_for_you does not exist');
+    $this->assertNull(\Drupal::service('extension.list.theme_engine')
+      ->getPathname('there_is_an_theme_engine_for_you'), 'Searching for an item that does not exist returns NULL.');
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
index dcc75a2d0c86154ea1b84ba11e34360898ad5b39..62f6abd200ff003b5bbf972d9e3936322088bff4 100644
--- a/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
@@ -2,13 +2,13 @@
 
 namespace Drupal\KernelTests\Core\Bootstrap;
 
-use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\KernelTests\KernelTestBase;
 
 /**
  * Tests that drupal_get_filename() works correctly.
  *
  * @group Bootstrap
+ * @group legacy
  */
 class GetFilenameTest extends KernelTestBase {
 
@@ -18,52 +18,20 @@ class GetFilenameTest extends KernelTestBase {
   protected static $modules = ['system'];
 
   /**
-   * {@inheritdoc}
+   * Tests drupal_get_filename() deprecation.
    */
-  public function register(ContainerBuilder $container) {
-    parent::register($container);
-    // Use the testing install profile.
-    $container->setParameter('install_profile', 'testing');
+  public function testDrupalGetFilename(): void {
+    $this->expectDeprecation('drupal_get_filename() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPathname() instead. See https://www.drupal.org/node/2940438');
+    $this->assertEquals('core/modules/system/system.info.yml', drupal_get_filename('module', 'system'));
   }
 
   /**
-   * Tests that drupal_get_filename() works when the file is not in database.
+   * Tests drupal_get_path() deprecation.
    */
-  public function testDrupalGetFilename() {
-    // Retrieving the location of a module.
-    $this->assertSame('core/modules/system/system.info.yml', drupal_get_filename('module', 'system'));
-
-    // Retrieving the location of a theme.
-    \Drupal::service('theme_installer')->install(['stark']);
-    $this->assertSame('core/themes/stark/stark.info.yml', drupal_get_filename('theme', 'stark'));
-
-    // Retrieving the location of a theme engine.
-    $this->assertSame('core/themes/engines/twig/twig.info.yml', drupal_get_filename('theme_engine', 'twig'));
-
-    // Retrieving the location of a profile. Profiles are a special case with
-    // a fixed location and naming.
-    $this->assertSame('core/profiles/testing/testing.info.yml', drupal_get_filename('profile', 'testing'));
-
-    // Set a custom error handler so we can ignore the file not found error.
-    set_error_handler(function ($severity, $message, $file, $line) {
-      // Skip error handling if this is a "file not found" error.
-      if (strstr($message, 'is missing from the file system:')) {
-        \Drupal::state()->set('get_filename_test_triggered_error', $message);
-        return;
-      }
-      throw new \ErrorException($message, 0, $severity, $file, $line);
-    });
-    $this->assertNull(drupal_get_filename('module', 'there_is_a_module_for_that'), 'Searching for an item that does not exist returns NULL.');
-    $this->assertEquals('The following module is missing from the file system: there_is_a_module_for_that', \Drupal::state()->get('get_filename_test_triggered_error'));
-
-    $this->assertNull(drupal_get_filename('theme', 'there_is_a_theme_for_you'), 'Searching for an item that does not exist returns NULL.');
-    $this->assertEquals('The following theme is missing from the file system: there_is_a_theme_for_you', \Drupal::state()->get('get_filename_test_triggered_error'));
-
-    $this->assertNull(drupal_get_filename('profile', 'there_is_an_install_profile_for_you'), 'Searching for an item that does not exist returns NULL.');
-    $this->assertEquals('The following profile is missing from the file system: there_is_an_install_profile_for_you', \Drupal::state()->get('get_filename_test_triggered_error'));
-
-    // Restore the original error handler.
-    restore_error_handler();
+  public function testDrupalGetPath(): void {
+    $this->expectDeprecation('drupal_get_path() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPath() instead. See https://www.drupal.org/node/2940438');
+    $this->expectDeprecation('drupal_get_filename() is deprecated in drupal:9.3.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionPathResolver::getPathname() instead. See https://www.drupal.org/node/2940438');
+    $this->assertEquals('core/modules/system', drupal_get_path('module', 'system'));
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigCRUDTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigCRUDTest.php
index b9345ad4327b463524e15e7cbcb5d29a8a2f0cb3..127c7fb06c1de14ed99a0fdd11fa841820b842a1 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigCRUDTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigCRUDTest.php
@@ -7,7 +7,6 @@
 use Drupal\Core\Config\Config;
 use Drupal\Core\Config\ConfigNameException;
 use Drupal\Core\Config\ConfigValueException;
-use Drupal\Core\Config\InstallStorage;
 use Drupal\Core\Config\DatabaseStorage;
 use Drupal\Core\Config\UnsupportedDataTypeConfigException;
 use Drupal\KernelTests\KernelTestBase;
@@ -270,7 +269,6 @@ public function testDataTypes() {
     $storage = new DatabaseStorage($this->container->get('database'), 'config');
     $name = 'config_test.types';
     $config = $this->config($name);
-    $original_content = file_get_contents(drupal_get_path('module', 'config_test') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY . "/$name.yml");
 
     // Verify variable data types are intact.
     $data = [
diff --git a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
index 928ac1cbfb5c98a292f11497e2bc2f9680f384fe..29b22bd6072bc22c95ab0e7928d002f4c04a6842 100644
--- a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
+++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
@@ -145,7 +145,8 @@ public function testCompileDIC() {
 
     // Check that the location of the new module is registered.
     $modules = $container->getParameter('container.modules');
-    $this->assertEquals(['type' => 'module', 'pathname' => drupal_get_filename('module', 'service_provider_test'), 'filename' => NULL], $modules['service_provider_test']);
+    $module_extension_list = $container->get('extension.list.module');
+    $this->assertEquals(['type' => 'module', 'pathname' => $module_extension_list->getPathname('service_provider_test'), 'filename' => NULL], $modules['service_provider_test']);
 
     // Check that the container itself is not among the persist IDs because it
     // does not make sense to persist the container itself.
diff --git a/core/tests/Drupal/KernelTests/Core/Extension/LegacyExtensionPathResolverTest.php b/core/tests/Drupal/KernelTests/Core/Extension/LegacyExtensionPathResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6755e4be66a129c67baaa12a77efe3f9db1afb7f
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Extension/LegacyExtensionPathResolverTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Extension;
+
+use Drupal\Core\Extension\ExtensionPathResolver;
+use Drupal\Core\Extension\ModuleExtensionList;
+use Drupal\Core\Extension\ProfileExtensionList;
+use Drupal\Core\Extension\ThemeEngineExtensionList;
+use Drupal\Core\Extension\ThemeExtensionList;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests the extension path resolver deprecations.
+ *
+ * @group legacy
+ * @group Module
+ */
+class LegacyExtensionPathResolverTest extends KernelTestBase {
+
+  /**
+   * @group legacy
+   */
+  public function testDeprecatedWarning() {
+    $this->expectDeprecation('Calling getPathname() with an invalid $type parameter is deprecated in drupal:9.3.0 and will throw an \Drupal\Core\Extension\Exception\UnknownExtensionTypeException in drupal:10.0.0. See https://www.drupal.org/node/2940438');
+    $module_extension_list = $this->prophesize(ModuleExtensionList::class);
+    $profile_extension_list = $this->prophesize(ProfileExtensionList::class);
+    $theme_extension_list = $this->prophesize(ThemeExtensionList::class);
+    $theme_engine_extension_list = $this->prophesize(ThemeEngineExtensionList::class);
+    $resolver = new ExtensionPathResolver(
+      $module_extension_list->reveal(),
+      $profile_extension_list->reveal(),
+      $theme_extension_list->reveal(),
+      $theme_engine_extension_list->reveal()
+    );
+
+    $this->assertEmpty($resolver->getPath('foo', 'bar'));
+
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
index b0f308e8ff9b4b679277761d1daceed19a2789ef..970ca6909fceb6d78037ca0c93daecf9a8ce299a 100644
--- a/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
@@ -36,7 +36,8 @@ protected function setUp(): void {
     parent::setUp();
     // Hardcode the location of the fixtures files as it is already known
     // and shouldn't change, and we don't yet have a way to retrieve their
-    // location from drupal_get_filename() in a cached way.
+    // location from \Drupal\Core\Extension\ExtensionList::getPathname() in a
+    // cached way.
     // @todo Remove as part of https://www.drupal.org/node/2186491
     $this->path = 'core/tests/fixtures/files';
     $this->fileSystem = $this->container->get('file_system');
diff --git a/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
index d2188d5884f0b34a4179d416c306142c175153a8..e8db17fe54a2e1e4cd24f208f11151ecf9d12d8e 100644
--- a/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\KernelTests\Core\Installer;
 
 use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\Extension\ProfileExtensionList;
 use Drupal\Core\StringTranslation\Translator\FileTranslation;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -45,11 +46,14 @@ public function testInstallerTranslationFiles() {
   public function testInstallerTranslationCache() {
     require_once 'core/includes/install.inc';
 
-    // Prime the drupal_get_filename() static cache with the location of the
-    // testing profile as it is not the currently active profile and we don't
-    // yet have any cached way to retrieve its location.
+    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname() static
+    // cache with the location of the testing profile as it isn't the currently
+    // active profile and we don't yet have any cached way to retrieve its
+    // location.
     // @todo Remove as part of https://www.drupal.org/node/2186491
-    drupal_get_filename('profile', 'testing', 'core/profiles/testing/testing.info.yml');
+    $profile_list = \Drupal::service('extension.list.profile');
+    assert($profile_list instanceof ProfileExtensionList);
+    $profile_list->setPathname('testing', 'core/profiles/testing/testing.info.yml');
 
     $info_en = install_profile_info('testing', 'en');
     $info_nl = install_profile_info('testing', 'nl');
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
index 91719ddb2f22e5f782825ae1c94713a33fe46741..3b3a0829a74ba0a50978c3e521471122e616582b 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\KernelTests\Core\Theme;
 
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Path\CurrentPathStack;
 use Drupal\Core\Path\PathMatcherInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
@@ -70,11 +71,14 @@ public function testMultipleSubThemes() {
     $theme_handler = \Drupal::service('theme_handler');
     \Drupal::service('theme_installer')->install(['test_basetheme', 'test_subtheme', 'test_subsubtheme']);
 
-    $registry_subsub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_subsubtheme');
+    $module_list = $this->container->get('extension.list.module');
+    assert($module_list instanceof ModuleExtensionList);
+
+    $registry_subsub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_subsubtheme', NULL, $module_list);
     $registry_subsub_theme->setThemeManager(\Drupal::theme());
-    $registry_sub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_subtheme');
+    $registry_sub_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_subtheme', NULL, $module_list);
     $registry_sub_theme->setThemeManager(\Drupal::theme());
-    $registry_base_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_basetheme');
+    $registry_base_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_basetheme', NULL, $module_list);
     $registry_base_theme->setThemeManager(\Drupal::theme());
 
     $preprocess_functions = $registry_subsub_theme->get()['theme_test_template_test']['preprocess functions'];
@@ -106,7 +110,9 @@ public function testSuggestionPreprocessFunctions() {
     $theme_handler = \Drupal::service('theme_handler');
     \Drupal::service('theme_installer')->install(['test_theme']);
 
-    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme');
+    $extension_list = $this->container->get('extension.list.module');
+    assert($extension_list instanceof ModuleExtensionList);
+    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme', NULL, $extension_list);
     $registry_theme->setThemeManager(\Drupal::theme());
 
     $suggestions = ['__kitten', '__flamingo'];
@@ -146,7 +152,9 @@ public function testThemeRegistryAlterByTheme() {
     \Drupal::service('theme_installer')->install(['test_theme']);
     $this->config('system.theme')->set('default', 'test_theme')->save();
 
-    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme');
+    $extension_list = $this->container->get('extension.list.module');
+    assert($extension_list instanceof ModuleExtensionList);
+    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme', NULL, $extension_list);
     $registry->setThemeManager(\Drupal::theme());
     $this->assertEquals('value', $registry->get()['theme_test_template_test']['variables']['additional']);
   }
@@ -234,7 +242,9 @@ public function testThemeTemplatesRegisteredByModules() {
     $theme_handler = \Drupal::service('theme_handler');
     \Drupal::service('theme_installer')->install(['test_theme']);
 
-    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme');
+    $extension_list = \Drupal::service('extension.list.module');
+    assert($extension_list instanceof ModuleExtensionList);
+    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme', NULL, $extension_list);
     $registry_theme->setThemeManager(\Drupal::theme());
 
     $expected = [
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php
index 222dca4d05fb2dab1a986380b765ce38537a07c5..c89220ec1743e469a7a21668c8dac5b622efaffa 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/Stable9TemplateOverrideTest.php
@@ -82,7 +82,7 @@ protected function installAllModules() {
    * Ensures that Stable 9 overrides all relevant core templates.
    */
   public function testStable9TemplateOverrides() {
-    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), 'stable9');
+    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), 'stable9', NULL, \Drupal::service('extension.list.module'));
     $registry->setThemeManager(\Drupal::theme());
 
     $registry_full = $registry->get();
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php
index b274dc179ae3decc8a00ae5696a21a17cca2b1b9..bcf7e9b40951ca1e2d5529831229b3e14ae0b8a1 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php
@@ -80,7 +80,7 @@ protected function installAllModules() {
    * Ensures that Stable overrides all relevant core templates.
    */
   public function testStableTemplateOverrides() {
-    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), 'stable');
+    $registry = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $this->themeHandler, \Drupal::service('theme.initialization'), 'stable', NULL, \Drupal::service('extension.list.module'));
     $registry->setThemeManager(\Drupal::theme());
 
     $registry_full = $registry->get();
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
index 161f66072420080fcf8ab27d81e5d446305c02bd..11983e4868c9152f31a3ce05686a00f6f295100b 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
@@ -131,7 +131,7 @@ public function testWhiteListChaining() {
       'field_term' => $this->term->id(),
     ]);
     $node->save();
-    $template = $environment->loadTemplate(drupal_get_path('theme', 'test_theme') . '/templates/node.html.twig');
+    $template = $environment->loadTemplate($this->getThemePath('test_theme') . '/templates/node.html.twig');
     $markup = $template->render(['node' => $node]);
     $this->setRawContent($markup);
     $this->assertText('Sometimes people are just jerks');
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 3cc63bcc1fc9f46dec5bbf37efab91db68a16170..0c379b9322b6fcfe257c7805c1edbe23058d040d 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -16,6 +16,7 @@
 use Drupal\Core\Site\Settings;
 use Drupal\Core\Test\TestDatabase;
 use Drupal\Tests\ConfigTestTrait;
+use Drupal\Tests\ExtensionListTestTrait;
 use Drupal\Tests\RandomGeneratorTrait;
 use Drupal\Tests\PhpUnitCompatibilityTrait;
 use Drupal\Tests\TestRequirementsTrait;
@@ -85,6 +86,7 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
   use AssertContentTrait;
   use RandomGeneratorTrait;
   use ConfigTestTrait;
+  use ExtensionListTestTrait;
   use TestRequirementsTrait;
   use PhpUnitWarnings;
   use PhpUnitCompatibilityTrait;
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 9d66b2e34e09e9d6a30924fb059a2d5ed6500541..29dee384c92291adaff980d75ccfc6d34b65b87d 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -74,6 +74,7 @@ abstract class BrowserTestBase extends TestCase {
   use PhpUnitWarnings;
   use PhpUnitCompatibilityTrait;
   use ExpectDeprecationTrait;
+  use ExtensionListTestTrait;
 
   /**
    * The database prefix of this test run.
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index fc5d60b12e9d1eb482ccb261e58180861b9b88f2..da914e76661526e89dfb0447a73b99a8efcb8703 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
 use Drupal\Core\Asset\LibrariesDirectoryFileFinder;
 use Drupal\Core\Asset\LibraryDiscoveryParser;
+use Drupal\Core\Extension\ExtensionPathResolver;
 use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
 use Drupal\Core\Theme\ActiveTheme;
 use Drupal\Core\Theme\ThemeManagerInterface;
@@ -79,6 +80,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
    */
   protected $librariesDirectoryFileFinder;
 
+  /**
+   * The mocked extension path resolver.
+   *
+   * @var \Drupal\Core\Extension\ExtensionPathResolver|\PHPUnit\Framework\MockObject\MockObject
+   */
+  protected $extensionPathResolver;
+
   /**
    * {@inheritdoc}
    */
@@ -98,7 +106,8 @@ protected function setUp(): void {
       ->willReturn($this->activeTheme);
     $this->streamWrapperManager = $this->createMock(StreamWrapperManagerInterface::class);
     $this->librariesDirectoryFileFinder = $this->createMock(LibrariesDirectoryFileFinder::class);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder);
+    $this->extensionPathResolver = $this->createMock(ExtensionPathResolver::class);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
   }
 
   /**
@@ -114,7 +123,10 @@ public function testBuildByExtensionSimple() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'example_module')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('example_module');
     $library = $libraries['example'];
@@ -141,7 +153,10 @@ public function testBuildByExtensionWithTheme() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('theme', 'example_theme', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('theme', 'example_theme')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('example_theme');
     $library = $libraries['example'];
@@ -165,7 +180,10 @@ public function testBuildByExtensionWithMissingLibraryFile() {
 
     $path = __DIR__ . '/library_test_files_not_existing';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'example_module')
+      ->willReturn($path);
 
     $this->assertSame($this->libraryDiscoveryParser->buildByExtension('example_module'), []);
   }
@@ -183,7 +201,10 @@ public function testInvalidLibrariesFile() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'invalid_file', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'invalid_file')
+      ->willReturn($path);
 
     $this->expectException(InvalidLibraryFileException::class);
     $this->libraryDiscoveryParser->buildByExtension('invalid_file');
@@ -202,7 +223,10 @@ public function testBuildByExtensionWithOnlyDependencies() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_module_only_dependencies', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'example_module_only_dependencies')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('example_module_only_dependencies');
     $this->assertArrayHasKey('example', $libraries);
@@ -221,7 +245,10 @@ public function testBuildByExtensionWithMissingInformation() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_module_missing_information', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'example_module_missing_information')
+      ->willReturn($path);
 
     $this->expectException(IncompleteLibraryDefinitionException::class);
     $this->expectExceptionMessage("Incomplete library definition for definition 'example' in extension 'example_module_missing_information'");
@@ -241,7 +268,10 @@ public function testVersion() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'versions', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'versions')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('versions');
 
@@ -271,7 +301,10 @@ public function testExternalLibraries() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'external', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'external')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('external');
     $library = $libraries['example_external'];
@@ -294,7 +327,10 @@ public function testDefaultCssWeights() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'css_weights', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'css_weights')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('css_weights');
     $library = $libraries['example'];
@@ -332,7 +368,10 @@ public function testJsWithPositiveWeight() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'js_positive_weight', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'js_positive_weight')
+      ->willReturn($path);
 
     $this->expectException(\UnexpectedValueException::class);
     $this->libraryDiscoveryParser->buildByExtension('js_positive_weight');
@@ -351,7 +390,10 @@ public function testLibraryWithCssJsSetting() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'css_js_settings', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'css_js_settings')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('css_js_settings');
     $library = $libraries['example'];
@@ -381,7 +423,10 @@ public function testLibraryWithDependencies() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'dependencies', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'dependencies')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('dependencies');
     $library = $libraries['example'];
@@ -407,7 +452,10 @@ public function testLibraryWithDataTypes() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'data_types', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'data_types')
+      ->willReturn($path);
 
     $this->libraryDiscoveryParser->setFileValidUri('public://test.css', TRUE);
     $this->libraryDiscoveryParser->setFileValidUri('public://test2.css', FALSE);
@@ -439,7 +487,10 @@ public function testLibraryWithJavaScript() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'js', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'js')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('js');
     $library = $libraries['example'];
@@ -462,7 +513,10 @@ public function testLibraryThirdPartyWithMissingLicense() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'licenses_missing_information', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'licenses_missing_information')
+      ->willReturn($path);
 
     $this->expectException(LibraryDefinitionMissingLicenseException::class);
     $this->expectExceptionMessage("Missing license information in library definition for definition 'no-license-info-but-remote' extension 'licenses_missing_information': it has a remote, but no license.");
@@ -482,7 +536,10 @@ public function testLibraryWithLicenses() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'licenses', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'licenses')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('licenses');
 
@@ -581,17 +638,21 @@ public function testLibraryOverride() {
     $this->themeManager->expects($this->any())
       ->method('getActiveTheme')
       ->willReturn($this->activeTheme);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder);
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen($this->root) + 1);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'example_module')
+      ->willReturn($path);
+
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
 
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
       ->with('example_module')
       ->will($this->returnValue(TRUE));
 
-    $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
-
     $libraries = $this->libraryDiscoveryParser->buildByExtension('example_module');
     $library = $libraries['example'];
 
@@ -631,16 +692,20 @@ public function testLibraryOverrideDeprecated() {
     $this->themeManager->expects($this->any())
       ->method('getActiveTheme')
       ->willReturn($this->activeTheme);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder);
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen($this->root) + 1);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'deprecated')
+      ->willReturn($path);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager, $this->librariesDirectoryFileFinder, $this->extensionPathResolver);
 
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
       ->with('deprecated')
       ->will($this->returnValue(TRUE));
 
-    $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'deprecated', $path);
     $this->libraryDiscoveryParser->buildByExtension('deprecated');
   }
 
@@ -668,7 +733,10 @@ public function testCssAssert($extension, $exception_message) {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', $extension, $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', $extension)
+      ->willReturn($path);
 
     $this->expectException(\AssertionError::class);
     $this->expectExceptionMessage($exception_message);
@@ -697,7 +765,10 @@ public function testNonCoreLibrariesFound() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_contrib_module', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'example_contrib_module')
+      ->willReturn($path);
 
     $this->librariesDirectoryFileFinder->expects($this->once())
       ->method('find')
@@ -725,8 +796,13 @@ public function testNonCoreLibrariesNotFound() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'example_contrib_module', $path);
-    $this->libraryDiscoveryParser->setPaths('profile', 'library_testing', 'profiles/library_testing');
+
+    $this->extensionPathResolver->expects($this->once())
+      ->method('getPath')
+      ->willReturnMap([
+        ['module', 'example_contrib_module', $path],
+        ['profile', 'library_testing', 'profiles/library_testing'],
+      ]);
 
     $this->librariesDirectoryFileFinder->expects($this->once())
       ->method('find')
@@ -755,7 +831,10 @@ public function testEmptyLibraryFile() {
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'empty', $path);
+    $this->extensionPathResolver->expects($this->atLeastOnce())
+      ->method('getPath')
+      ->with('module', 'empty')
+      ->willReturn($path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('empty');
 
@@ -769,18 +848,8 @@ public function testEmptyLibraryFile() {
  */
 class TestLibraryDiscoveryParser extends LibraryDiscoveryParser {
 
-  protected $paths;
-
   protected $validUris;
 
-  protected function drupalGetPath($type, $name) {
-    return isset($this->paths[$type][$name]) ? $this->paths[$type][$name] : NULL;
-  }
-
-  public function setPaths($type, $name, $path) {
-    $this->paths[$type][$name] = $path;
-  }
-
   protected function fileValidUri($source) {
     return isset($this->validUris[$source]) ? $this->validUris[$source] : FALSE;
   }
diff --git a/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php
index c01f8d8d0b984eb0a083fc055c7b17ce51c0e42e..2588c2ebf26803603db89fff0db648100ddde70b 100644
--- a/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php
@@ -65,9 +65,6 @@ abstract protected function getPluginId();
   /**
    * Returns the module name and the module directory for the plugin.
    *
-   * Function drupal_get_path() cannot be used here, because it is not available
-   * in Drupal PHPUnit tests.
-   *
    * @return array
    *   A one-dimensional array containing the following strings:
    *   - The module name.
diff --git a/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php b/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php
index 638a0b1a7ce05a3b432c87665e285c1e3fb7f60a..8414099b369d9809e81cd08286c58c8283eed86d 100644
--- a/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\Core\Theme;
 
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Theme\ActiveTheme;
 use Drupal\Core\Theme\Registry;
 use Drupal\Tests\UnitTestCase;
@@ -64,6 +65,13 @@ class RegistryLegacyTest extends UnitTestCase {
    */
   protected $themeManager;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList|\PHPUnit\Framework\MockObject\MockObject
+   */
+  protected $moduleList;
+
   /**
    * {@inheritdoc}
    */
@@ -76,6 +84,7 @@ protected function setUp(): void {
     $this->themeHandler = $this->createMock('Drupal\Core\Extension\ThemeHandlerInterface');
     $this->themeInitialization = $this->createMock('Drupal\Core\Theme\ThemeInitializationInterface');
     $this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface');
+    $this->moduleList = $this->createMock(ModuleExtensionList::class);
 
     $this->setupTheme();
   }
@@ -111,6 +120,10 @@ public function testGetLegacyThemeFunctionRegistryForModule() {
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('getModuleList')
       ->willReturn([]);
+    $this->moduleList->expects($this->once())
+      ->method('getPath')
+      ->with('theme_legacy_test')
+      ->willReturn('core/modules/system/tests/modules/theme_legacy_test');
 
     $registry = $this->registry->get();
 
@@ -133,7 +146,17 @@ public function testGetLegacyThemeFunctionRegistryForModule() {
   protected function setupTheme() {
     $this->registry = $this->getMockBuilder(Registry::class)
       ->setMethods(['getPath'])
-      ->setConstructorArgs([$this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization])
+      ->setConstructorArgs([
+        $this->root,
+        $this->cache,
+        $this->lock,
+        $this->moduleHandler,
+        $this->themeHandler,
+        $this->themeInitialization,
+        NULL,
+        NULL,
+        $this->moduleList,
+      ])
       ->getMock();
     $this->registry->expects($this->any())
       ->method('getPath')
diff --git a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
index 41e95e4283470af6c61fb2913229c60c8f9d2a9e..b5a86ffa6b5f237debade1f69dc2d362419fdc21 100644
--- a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\Core\Theme;
 
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Theme\ActiveTheme;
 use Drupal\Core\Theme\Registry;
 use Drupal\Tests\UnitTestCase;
@@ -61,6 +62,13 @@ class RegistryTest extends UnitTestCase {
    */
   protected $themeManager;
 
+  /**
+   * The module list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList|\PHPUnit\Framework\MockObject\MockObject
+   */
+  protected $moduleList;
+
   /**
    * The list of functions that get_defined_functions() should provide.
    *
@@ -80,7 +88,7 @@ protected function setUp(): void {
     $this->themeHandler = $this->createMock('Drupal\Core\Extension\ThemeHandlerInterface');
     $this->themeInitialization = $this->createMock('Drupal\Core\Theme\ThemeInitializationInterface');
     $this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface');
-
+    $this->moduleList = $this->createMock(ModuleExtensionList::class);
     $this->setupTheme();
   }
 
@@ -136,6 +144,10 @@ public function testGetRegistryForModule() {
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('getModuleList')
       ->willReturn([]);
+    $this->moduleList->expects($this->exactly(2))
+      ->method('getPath')
+      ->with('theme_test')
+      ->willReturn('core/modules/system/tests/modules/theme_test');
 
     $registry = $this->registry->get();
 
@@ -473,7 +485,7 @@ public function providerTestPostProcessExtension() {
   protected function setupTheme() {
     $this->registry = $this->getMockBuilder(Registry::class)
       ->setMethods(['getPath'])
-      ->setConstructorArgs([$this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization])
+      ->setConstructorArgs([$this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization, NULL, NULL, $this->moduleList])
       ->getMock();
     $this->registry->expects($this->any())
       ->method('getPath')
diff --git a/core/tests/Drupal/Tests/ExtensionListTestTrait.php b/core/tests/Drupal/Tests/ExtensionListTestTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..088237893bb70aeb567c751f2719b7caf74a063a
--- /dev/null
+++ b/core/tests/Drupal/Tests/ExtensionListTestTrait.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\Tests;
+
+/**
+ * Provides extension list methods.
+ */
+trait ExtensionListTestTrait {
+
+  /**
+   * Gets the path for the specified module.
+   *
+   * @param string $module_name
+   *   The module name.
+   *
+   * @return string
+   *   The Drupal-root relative path to the module directory.
+   *
+   * @throws \Drupal\Core\Extension\Exception\UnknownExtensionException
+   *   If the module does not exist.
+   */
+  protected function getModulePath(string $module_name): string {
+    return \Drupal::service('extension.list.module')->getPath($module_name);
+  }
+
+  /**
+   * Gets the path for the specified theme.
+   *
+   * @param string $theme_name
+   *   The theme name.
+   *
+   * @return string
+   *   The Drupal-root relative path to the theme directory.
+   *
+   * @throws \Drupal\Core\Extension\Exception\UnknownExtensionException
+   *   If the theme does not exist.
+   */
+  protected function getThemePath(string $theme_name): string {
+    return \Drupal::service('extension.list.theme')->getPath($theme_name);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/UpdatePathTestTrait.php b/core/tests/Drupal/Tests/UpdatePathTestTrait.php
index 3978f7e37c4139ff7502358688e251ecfd658a11..6980d0ce0c7d046462d5f58dfa1b25bcb154ff81 100644
--- a/core/tests/Drupal/Tests/UpdatePathTestTrait.php
+++ b/core/tests/Drupal/Tests/UpdatePathTestTrait.php
@@ -87,8 +87,10 @@ protected function runUpdates($update_url = NULL) {
       $modules_installed = FALSE;
       // Modules that are in configuration but not the module handler have been
       // installed.
+      /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
+      $module_list = $this->container->get('extension.list.module');
       foreach (array_keys(array_diff_key($config_module_list, $module_handler_list)) as $module) {
-        $module_handler->addModule($module, drupal_get_path('module', $module));
+        $module_handler->addModule($module, $module_list->getPath($module));
         $modules_installed = TRUE;
       }
       $modules_uninstalled = FALSE;
diff --git a/core/themes/olivero/olivero.theme b/core/themes/olivero/olivero.theme
index 500ac751ff7a2aa7c4dc2f1c8fb1df67664b34ba..5ab66a751d2c824da568c57c480e973593431b93 100644
--- a/core/themes/olivero/olivero.theme
+++ b/core/themes/olivero/olivero.theme
@@ -24,7 +24,7 @@ function olivero_preprocess_html(&$variables) {
 
   // So fonts can be preloaded from base theme in the event Olivero is used as a
   // subtheme.
-  $variables['olivero_path'] = drupal_get_path('theme', 'olivero');
+  $variables['olivero_path'] = \Drupal::service('extension.list.theme')->getPath('olivero');
 
   $query_string = \Drupal::state()->get('system.css_js_query_string') ?: '0';