diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 7c8799a..18fcd8d 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -9,6 +9,8 @@
 
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
 use Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait;
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Plugin\PluginManagerInterface;
@@ -36,6 +38,13 @@ class DefaultPluginManager extends PluginManagerBase implements PluginManagerInt
   protected $cacheBackend;
 
   /**
+   * The cache contexts manager.
+   *
+   * @var \Drupal\Core\Cache\Context\CacheContextsManager|null
+   */
+  protected $cacheContextsManager;
+
+  /**
    * The cache key.
    *
    * @var string
@@ -152,15 +161,32 @@ public function __construct($subdir, \Traversable $namespaces, ModuleHandlerInte
    *   definitions of a plugin manager, call that plugin manager's
    *   clearCachedDefinitions() method. Only use cache tags when cached plugin
    *   definitions should be cleared along with other, related cache entries.
+   * @param \Drupal\Core\Cache\Context\CacheContextsManager|null $cache_contexts_manager
+   *   The cache contexts manager (recommended), or NULL to retrieve it from the
+   *   service container automatically.
    */
-  public function setCacheBackend(CacheBackendInterface $cache_backend, $cache_key, array $cache_tags = array()) {
+  public function setCacheBackend(CacheBackendInterface $cache_backend, $cache_key, array $cache_tags = [], CacheContextsManager $cache_contexts_manager = NULL) {
     Cache::validateTags($cache_tags);
     $this->cacheBackend = $cache_backend;
+    $this->cacheContextsManager = $cache_contexts_manager;
     $this->cacheKey = $cache_key;
     $this->cacheTags = $cache_tags;
   }
 
   /**
+   * Gets the cache contexts manager.
+   *
+   * @return \Drupal\Core\Cache\Context\CacheContextsManager
+   */
+  protected function getCacheContextsManager() {
+    if (!$this->cacheContextsManager) {
+      $this->cacheContextsManager = \Drupal::service('cache_contexts"manager');
+    }
+
+    return $this->cacheContextsManager;
+  }
+
+  /**
    * Initializes the alter hook.
    *
    * @param string $alter_hook
@@ -222,7 +248,20 @@ protected function getCachedDefinitions() {
    *   List of definitions to store in cache.
    */
   protected function setCachedDefinitions($definitions) {
-    $this->cacheSet($this->cacheKey, $definitions, Cache::PERMANENT, $this->cacheTags);
+    $cacheable_metadata = new CacheableMetadata();
+    $cacheable_metadata->setCacheMaxAge(Cache::PERMANENT);
+    $cacheable_metadata->setCacheTags($this->cacheTags);
+    $cacheable_metadata->setCacheContexts([$this->cacheKey]);
+    foreach ($definitions as $plugin_definition) {
+      if (isset($plugin_definition['cache'])) {
+        $plugin_definition_cacheable_metadata = $plugin_definition['cache'];
+        if ($plugin_definition_cacheable_metadata instanceof CacheableMetadata) {
+          $cacheable_metadata = $cacheable_metadata->merge($plugin_definition_cacheable_metadata);
+        }
+      }
+    }
+    $cache_key = $this->cacheContextsManager->convertTokensToKeys($cacheable_metadata->getCacheContexts());
+    $this->cacheSet($cache_key, $definitions, $cacheable_metadata->getCacheMaxAge(), $cacheable_metadata->getCacheTags());
     $this->definitions = $definitions;
   }
 
