diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinition.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinition.php
new file mode 100644
index 0000000..ed1ac91
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinition.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Provides object-based plugin definitions.
+ */
+class PluginDefinition implements PluginDefinitionInterface {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  protected $id;
+
+  /**
+   * A fully qualified class name.
+   *
+   * @var string
+   */
+  protected $class;
+
+  /**
+   * The plugin provider.
+   *
+   * @var string
+   */
+  protected $provider;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function id() {
+    return $this->id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setClass($class) {
+    $this->class = $class;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getClass() {
+    return $this->class;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getProvider() {
+    return $this->provider;
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
index ed2cc8f..249b4c9 100644
--- a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
@@ -12,6 +12,14 @@
 interface PluginDefinitionInterface {
 
   /**
+   * Gets the unique identifier of the plugin definition.
+   *
+   * @return string
+   *   The unique identifier of the plugin definition.
+   */
+  public function id();
+
+  /**
    * Sets the class.
    *
    * @param string $class
@@ -32,4 +40,15 @@ public function setClass($class);
    */
   public function getClass();
 
+  /**
+   * Gets the plugin provider.
+   *
+   * The provider is the name of the module that provides the plugin, or "core',
+   * or "component".
+   *
+   * @return string
+   *   The provider.
+   */
+  public function getProvider();
+
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index bab091a..8728fb9 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Component\Plugin\Definition\PluginDefinition;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\Exception\EntityTypeIdLengthException;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
@@ -12,7 +13,7 @@
  *
  * @ingroup entity_api
  */
-class EntityType implements EntityTypeInterface {
+class EntityType extends PluginDefinition implements EntityTypeInterface {
 
   use StringTranslationTrait;
 
@@ -52,20 +53,6 @@ class EntityType implements EntityTypeInterface {
   protected $id;
 
   /**
-   * The name of the provider of this entity type.
-   *
-   * @var string
-   */
-  protected $provider;
-
-  /**
-   * The name of the entity type class.
-   *
-   * @var string
-   */
-  protected $class;
-
-  /**
    * The name of the original entity type class.
    *
    * This is only set if the class name is changed.
@@ -391,27 +378,6 @@ public function hasKey($key) {
   /**
    * {@inheritdoc}
    */
-  public function id() {
-    return $this->id;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getProvider() {
-    return $this->provider;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getClass() {
-    return $this->class;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getOriginalClass() {
     return $this->originalClass ?: $this->class;
   }
@@ -425,8 +391,8 @@ public function setClass($class) {
       // class, assume that is the original class name.
       $this->originalClass = $this->class;
     }
-    $this->class = $class;
-    return $this;
+
+    return parent::setClass($class);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 5388a3e..aac547f 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -56,14 +56,6 @@ public function set($property, $value);
   public function id();
 
   /**
-   * Gets the name of the provider of this entity type.
-   *
-   * @return string
-   *   The name of the provider of this entity type.
-   */
-  public function getProvider();
-
-  /**
    * Gets the name of the original entity type class.
    *
    * In case the class name was changed with setClass(), this will return
diff --git a/core/lib/Drupal/Core/Layout/LayoutDefinition.php b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
index 9fab205..a319313 100644
--- a/core/lib/Drupal/Core/Layout/LayoutDefinition.php
+++ b/core/lib/Drupal/Core/Layout/LayoutDefinition.php
@@ -3,6 +3,7 @@
 namespace Drupal\Core\Layout;
 
 use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
+use Drupal\Component\Plugin\Definition\PluginDefinition;
 
 /**
  * Provides an implementation of a layout definition and its metadata.
@@ -12,23 +13,7 @@
  *   experimental modules and development releases of contributed modules.
  *   See https://www.drupal.org/core/experimental for more information.
  */
-class LayoutDefinition implements PluginDefinitionInterface, DerivablePluginDefinitionInterface {
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  protected $id;
-
-  /**
-   * The name of the provider of this layout definition.
-   *
-   * @todo Make protected after https://www.drupal.org/node/2818653.
-   *
-   * @var string
-   */
-  public $provider;
+class LayoutDefinition extends PluginDefinition implements PluginDefinitionInterface, DerivablePluginDefinitionInterface {
 
   /**
    * The name of the deriver of this layout definition, if any.
@@ -131,13 +116,6 @@ class LayoutDefinition implements PluginDefinitionInterface, DerivablePluginDefi
   protected $default_region;
 
   /**
-   * The name of the layout class.
-   *
-   * @var string
-   */
-  protected $class;
-
-  /**
    * Any additional properties and values.
    *
    * @var array
@@ -196,31 +174,6 @@ public function set($property, $value) {
   }
 
   /**
-   * Gets the unique identifier of the layout definition.
-   *
-   * @return string
-   *   The unique identifier of the layout definition.
-   */
-  public function id() {
-    return $this->id;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getClass() {
-    return $this->class;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setClass($class) {
-    $this->class = $class;
-    return $this;
-  }
-
-  /**
    * Gets the human-readable name of the layout definition.
    *
    * @return string|\Drupal\Core\StringTranslation\TranslatableMarkup
@@ -500,16 +453,6 @@ public function setDefaultRegion($default_region) {
   }
 
   /**
-   * Gets the name of the provider of this layout definition.
-   *
-   * @return string
-   *   The name of the provider of this layout definition.
-   */
-  public function getProvider() {
-    return $this->provider;
-  }
-
-  /**
    * Gets the config dependencies of this layout definition.
    *
    * @return array
diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index 62decb2..294e08b 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Plugin;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
 use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface;
 use Drupal\Core\Cache\CacheableDependencyInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
@@ -285,12 +286,8 @@ protected function findDefinitions() {
     // If this plugin was provided by a module that does not exist, remove the
     // plugin definition.
     foreach ($definitions as $plugin_id => $plugin_definition) {
-      // If the plugin definition is an object, attempt to convert it to an
-      // array, if that is not possible, skip further processing.
-      if (is_object($plugin_definition) && !($plugin_definition = (array) $plugin_definition)) {
-        continue;
-      }
-      if (isset($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array('core', 'component')) && !$this->providerExists($plugin_definition['provider'])) {
+      $provider = $this->extractProviderFromDefinition($plugin_definition);
+      if ($provider && !in_array($provider, array('core', 'component')) && !$this->providerExists($provider)) {
         unset($definitions[$plugin_id]);
       }
     }
@@ -298,6 +295,31 @@ protected function findDefinitions() {
   }
 
   /**
+   * Extracts the provider from a plugin definition.
+   *
+   * @param mixed $plugin_definition
+   *   The plugin definition. Usually either an array or an instance of
+   *   \Drupal\Component\Plugin\Definition\PluginDefinitionInterface
+   *
+   * @return string|null
+   *   The provider string, if it exists. NULL otherwise.
+   */
+  protected function extractProviderFromDefinition($plugin_definition) {
+    if ($plugin_definition instanceof PluginDefinitionInterface) {
+      return $plugin_definition->getProvider();
+    }
+
+    // Attempt to convert the plugin definition to an array.
+    if (is_object($plugin_definition)) {
+      $plugin_definition = (array) $plugin_definition;
+    }
+
+    if (isset($plugin_definition['provider'])) {
+      return $plugin_definition['provider'];
+    }
+  }
+
+  /**
    * Invokes the hook to alter the definitions if the alter hook is set.
    *
    * @param $definitions
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index ffdac5a..4ced547 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\Core\Plugin;
 
+use Drupal\Component\Plugin\Definition\PluginDefinition;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
@@ -360,6 +361,32 @@ public function testGetCacheMaxAge() {
   }
 
   /**
+   * @covers ::findDefinitions
+   * @covers ::extractProviderFromDefinition
+   */
+  public function testProviderExists() {
+    $definitions = [];
+    $definitions['array_based_found'] = ['provider' => 'module_found'];
+    $definitions['array_based_missing'] = ['provider' => 'module_missing'];
+    $definitions['stdclass_based_found'] = (object) ['provider' => 'module_found'];
+    $definitions['stdclass_based_missing'] = (object) ['provider' => 'module_missing'];
+    $definitions['classed_object_found'] = new ObjectDefinition(['provider' => 'module_found']);
+    $definitions['classed_object_missing'] = new ObjectDefinition(['provider' => 'module_missing']);
+
+    $expected = [];
+    $expected['array_based_found'] = $definitions['array_based_found'];
+    $expected['stdclass_based_found'] = $definitions['stdclass_based_found'];
+    $expected['classed_object_found'] = $definitions['classed_object_found'];
+
+    $module_handler = $this->prophesize(ModuleHandlerInterface::class);
+    $module_handler->moduleExists('module_found')->willReturn(TRUE)->shouldBeCalled();
+    $module_handler->moduleExists('module_missing')->willReturn(FALSE)->shouldBeCalled();
+    $plugin_manager = new TestPluginManager($this->namespaces, $definitions, $module_handler->reveal());
+    $result = $plugin_manager->getDefinitions();
+    $this->assertEquals($expected, $result);
+  }
+
+  /**
    * @covers ::processDefinition
    * @dataProvider providerTestProcessDefinition
    */
@@ -453,3 +480,17 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
   }
 
 }
+class ObjectDefinition extends PluginDefinition {
+
+  /**
+   * ObjectDefinition constructor.
+   *
+   * @param array $definition
+   */
+  public function __construct(array $definition) {
+    foreach ($definition as $property => $value) {
+      $this->{$property} = $value;
+    }
+  }
+
+}
