diff --git a/README.md b/README.md
index 8e620b2764048663ffd9fc4bb62d167baf7d929b..fec02eb438f3a5bf2b93afedd30f9c4496e2d699 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,3 @@
-## Core patch(es) needed
-* https://www.drupal.org/project/drupal/issues/3065207
-
 ## Areas to work on
 
 * Storage:
diff --git a/config/install/trash.settings.yml b/config/install/trash.settings.yml
new file mode 100644
index 0000000000000000000000000000000000000000..798f8c391c1849e54fb70591306baf4edc101404
--- /dev/null
+++ b/config/install/trash.settings.yml
@@ -0,0 +1 @@
+enabled_entity_types: { }
diff --git a/config/schema/trash.schema.yml b/config/schema/trash.schema.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f7ec0d9cfb3ea35befcab37e1eac9fffd9d0a1dd
--- /dev/null
+++ b/config/schema/trash.schema.yml
@@ -0,0 +1,8 @@
+trash.settings:
+  type: config_object
+  mapping:
+    enabled_entity_types:
+      label: Enabled entity types
+      type: sequence
+      sequence:
+        type: string
diff --git a/src/Entity/Query/QueryTrait.php b/src/Entity/Query/QueryTrait.php
index 6a471b55130b14176c28815c77f768124e350f93..140c5b5365c6dc2bf52908b4975ee45fb52462db 100644
--- a/src/Entity/Query/QueryTrait.php
+++ b/src/Entity/Query/QueryTrait.php
@@ -38,14 +38,12 @@ trait QueryTrait {
   public function prepare() {
     parent::prepare();
 
-    if (!in_array($this->entityTypeId, _trash_supported_entity_types(), TRUE)) {
+    if (!\Drupal::service('trash.manager')->isEntityTypeEnabled($this->entityType)) {
       return $this;
     }
 
-    assert($this->entityType->hasKey('deleted'));
-
     $revision_key = $this->entityType->getKey('revision');
-    $deleted_key = $this->entityType->getKey('deleted');
+    $deleted_key = 'deleted';
     $skip_deleted_filter = FALSE;
     // Skip adding a deleted flag for revisions as well as an explicit filter
     // on deleted, so you can still list deleted content, if needed.
@@ -64,10 +62,10 @@ trait QueryTrait {
       // @todo Do we need support for listing deleted and not deleted entities
       // at the same time?
       if ($this->isDeleted) {
-        $this->condition($deleted_key, 0, '>');
+        $this->exists($deleted_key);
       }
       else {
-        $this->condition($deleted_key, 0);
+        $this->notExists($deleted_key);
       }
     }
     return $this;
diff --git a/src/EventSubscriber/TrashConfigSubscriber.php b/src/EventSubscriber/TrashConfigSubscriber.php
new file mode 100644
index 0000000000000000000000000000000000000000..bab82b1ce95c87c6a1dbddf83fb3c60cc2cb6fec
--- /dev/null
+++ b/src/EventSubscriber/TrashConfigSubscriber.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\trash\EventSubscriber;
+
+use Drupal\Core\Config\ConfigCrudEvent;
+use Drupal\Core\Config\ConfigEvents;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\trash\TrashManagerInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Listens to the config save event for trash.settings.
+ */
+class TrashConfigSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The Trash manager.
+   *
+   * @var \Drupal\trash\TrashManagerInterface
+   */
+  protected $trashManager;
+
+  /**
+   * Constructs the TrashConfigSubscriber.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\trash\TrashManagerInterface $trash_manager
+   *   The trash manager.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, TrashManagerInterface $trash_manager) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->trashManager = $trash_manager;
+  }
+
+  /**
+   * Updates entity type definitions and ensures routes are rebuilt when needed.
+   *
+   * @param \Drupal\Core\Config\ConfigCrudEvent $event
+   *   The ConfigCrudEvent to process.
+   */
+  public function onSave(ConfigCrudEvent $event) {
+    $entity_types = $this->entityTypeManager->getDefinitions();
+    if ($event->getConfig()->getName() === 'trash.settings' && $event->isChanged('enabled_entity_types')) {
+      $enabled_entity_types = $event->getConfig()->get('enabled_entity_types');
+      $original_enabled_entity_types = $event->getConfig()->getOriginal('enabled_entity_types') ?? [];
+
+      foreach ($enabled_entity_types as $entity_type_id) {
+        if (!in_array($entity_type_id, $original_enabled_entity_types, TRUE)) {
+          $this->trashManager->enableEntityType($entity_types[$entity_type_id]);
+        }
+      }
+
+      foreach ($original_enabled_entity_types as $entity_type_id) {
+        if (!in_array($entity_type_id, $enabled_entity_types, TRUE)) {
+          $this->trashManager->disableEntityType($entity_types[$entity_type_id]);
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[ConfigEvents::SAVE][] = ['onSave'];
+    return $events;
+  }
+
+}
diff --git a/src/Form/TrashSettingsForm.php b/src/Form/TrashSettingsForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..b007f87389ad34971fc55b02e4420c304527f1f7
--- /dev/null
+++ b/src/Form/TrashSettingsForm.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Drupal\trash\Form;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
+use Drupal\Core\Form\ConfigFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Configure Trash settings for this site.
+ */
+class TrashSettingsForm extends ConfigFormBase {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity field manager.
+   *
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
+   */
+  protected $entityFieldManager;
+
+  /**
+   * Constructs a PathautoSettingsForm.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   Defines the configuration object factory.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   Manages entity type plugin definitions.
+   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
+   *   Manages the discovery of entity fields.
+   */
+  public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager) {
+    parent::__construct($config_factory);
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityFieldManager = $entity_field_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('config.factory'),
+      $container->get('entity_type.manager'),
+      $container->get('entity_field.manager'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'trash_settings_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEditableConfigNames() {
+    return ['trash.settings'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $config = $this->config('trash.settings');
+
+    $form['enabled_entity_types'] = [
+      '#type' => 'details',
+      '#open' => TRUE,
+      '#title' => $this->t('Enabled entity types'),
+      '#description' => $this->t('Enable to add a deleted field and allow to define alias patterns for the given type. Disabled types already define a path field themselves or currently have a pattern.'),
+      '#tree' => TRUE,
+    ];
+
+    // Get all applicable entity types.
+    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
+      if (is_subclass_of($entity_type->getStorageClass(), SqlEntityStorageInterface::class)) {
+        $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type_id);
+        $form['enabled_entity_types'][$entity_type_id] = [
+          '#type' => 'checkbox',
+          '#title' => $entity_type->getLabel(),
+          '#default_value' => isset($field_definitions['deleted']) || in_array($entity_type_id, $config->get('enabled_entity_types')),
+          '#disabled' => isset($field_definitions['deleted']) && ($field_definitions['deleted']->getProvider() !== 'trash'),
+        ];
+      }
+    }
+
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $config = $this->config('trash.settings');
+    $form_state->cleanValues();
+
+    foreach ($form_state->getValues() as $key => $value) {
+      if ($key == 'enabled_entity_types') {
+        $enabled_entity_types = [];
+        foreach ($value as $entity_type_id => $enabled) {
+          $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type_id);
+          // Verify that the entity type is enabled and that it is not defined
+          // or defined by us before adding it to the configuration, so that
+          // we do not store an entity type that cannot be enabled or disabled.
+          if ($enabled && (!isset($field_definitions['deleted']) || ($field_definitions['deleted']->getProvider() === 'trash'))) {
+            $enabled_entity_types[] = $entity_type_id;
+          }
+        }
+        $value = $enabled_entity_types;
+      }
+      $config->set($key, $value);
+    }
+    $config->save();
+
+    parent::submitForm($form, $form_state);
+  }
+
+}
diff --git a/src/TrashEntityTypeManager.php b/src/TrashEntityTypeManager.php
index ffdad881ded6dca623187f91f59a954acf586e47..3cc95cc7397cf8d1aa6b8193b72c415987008eab 100644
--- a/src/TrashEntityTypeManager.php
+++ b/src/TrashEntityTypeManager.php
@@ -5,7 +5,6 @@ namespace Drupal\trash;
 use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\PhpStorage\PhpStorageFactory;
 use Drupal\Core\Plugin\DefaultPluginManager;
 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -22,13 +21,6 @@ class TrashEntityTypeManager extends DefaultPluginManager implements EntityTypeM
    */
   protected $entityTypeManager;
 
-  /**
-   * The PhpStorage object used for storing the generated storage classes.
-   *
-   * @var \Drupal\Component\PhpStorage\PhpStorageInterface
-   */
-  protected $storage;
-
   /**
    * Contains instantiated storage handlers keyed by entity type.
    *
@@ -41,7 +33,6 @@ class TrashEntityTypeManager extends DefaultPluginManager implements EntityTypeM
    */
   public function __construct(EntityTypeManagerInterface $entity_type_manager) {
     $this->entityTypeManager = $entity_type_manager;
-    $this->storage = PhpStorageFactory::get('trash');
   }
 
   /**
@@ -170,7 +161,7 @@ class TrashEntityTypeManager extends DefaultPluginManager implements EntityTypeM
    * {@inheritdoc}
    */
   public function createHandlerInstance($class, EntityTypeInterface $definition = NULL) {
-    if ($definition->hasKey('deleted')) {
+    if (\Drupal::service('trash.manager')->isEntityTypeEnabled($definition)) {
       $class = _trash_generate_storage_class($class);
     }
 
diff --git a/src/TrashManager.php b/src/TrashManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..887a888e9e261d17fcfe2f1077c65ec0f0edce51
--- /dev/null
+++ b/src/TrashManager.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace Drupal\trash;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
+use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+
+/**
+ * Provides the Trash manager.
+ */
+class TrashManager implements TrashManagerInterface {
+
+  /**
+   * The entity definition update manager.
+   *
+   * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
+   */
+  protected $entityDefinitionUpdateManager;
+
+  /**
+   * The last installed schema definitions.
+   *
+   * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
+   */
+  protected $entityLastInstalledSchemaRepository;
+
+  /**
+   * The config factory service.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Constructs a new TrashManager.
+   *
+   * @param \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $entity_definition_update_manager
+   *   The entity definition update manager.
+   * @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository
+   *   The last installed schema repository service.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
+   */
+  public function __construct(EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository, ConfigFactoryInterface $config_factory) {
+    $this->entityDefinitionUpdateManager = $entity_definition_update_manager;
+    $this->entityLastInstalledSchemaRepository = $entity_last_installed_schema_repository;
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEntityTypeSupported(EntityTypeInterface $entity_type) : bool {
+    return is_subclass_of($entity_type->getStorageClass(), SqlEntityStorageInterface::class);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEntityTypeEnabled(EntityTypeInterface $entity_type) : bool {
+    return in_array($entity_type->id(), $this->configFactory->get('trash.settings')->get('enabled_entity_types'), TRUE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function enableEntityType(EntityTypeInterface $entity_type) {
+    $field_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type->id());
+
+    if (!$this->isEntityTypeSupported($entity_type)) {
+      throw new \InvalidArgumentException("Trash integration can not be enabled for the {$entity_type->id()} entity type.");
+    }
+
+    if (isset($field_storage_definitions['deleted'])) {
+      if ($field_storage_definitions['deleted']->getProvider() !== 'trash') {
+        throw new \InvalidArgumentException("The {$entity_type->id()} entity type already has a 'deleted' field.");
+      }
+      else {
+        throw new \InvalidArgumentException("Trash integration is already enabled for the {$entity_type->id()} entity type.");
+      }
+    }
+
+    $storage_definition = BaseFieldDefinition::create('timestamp')
+      ->setLabel(t('Deleted'))
+      ->setDescription(t('Time when the item got deleted'))
+      ->setInternal(TRUE)
+      ->setTranslatable(FALSE)
+      ->setRevisionable(TRUE);
+
+    $this->entityDefinitionUpdateManager->installFieldStorageDefinition('deleted', $entity_type->id(), 'trash', $storage_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function disableEntityType(EntityTypeInterface $entity_type) {
+    $field_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type->id());
+    if (isset($field_storage_definitions['deleted'])) {
+      $this->entityDefinitionUpdateManager->uninstallFieldStorageDefinition($field_storage_definitions['deleted']);
+    }
+  }
+
+}
diff --git a/src/TrashManagerInterface.php b/src/TrashManagerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0837b2fd6d9e105723912024393079bcec99a616
--- /dev/null
+++ b/src/TrashManagerInterface.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\trash;
+
+use Drupal\Core\Entity\EntityTypeInterface;
+
+/**
+ * Provides an interface for the Trash manager.
+ */
+interface TrashManagerInterface {
+
+  /**
+   * Determines whether an entity type is supported by Trash.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   An entity type object.
+   *
+   * @return bool
+   */
+  public function isEntityTypeSupported(EntityTypeInterface $entity_type) : bool;
+
+  /**
+   * Determines whether Trash integration is enabled for an entity type.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   An entity type object.
+   *
+   * @return bool
+   */
+  public function isEntityTypeEnabled(EntityTypeInterface $entity_type) : bool;
+
+  /**
+   * Enables Trash integration for an entity type.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   An entity type object.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when Trash integration can not be enabled or is already enabled
+   *   for an entity type.
+   */
+  public function enableEntityType(EntityTypeInterface $entity_type);
+
+  /**
+   * Disables Trash integration for an entity type.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   An entity type object.
+   */
+  public function disableEntityType(EntityTypeInterface $entity_type);
+
+}
diff --git a/src/TrashStorageTrait.php b/src/TrashStorageTrait.php
index 86962be6ebcca260ef8c5b32f64c9b0c5316c3f3..e4b4b9dd8603ca9348f94b83095e02408aec8748 100644
--- a/src/TrashStorageTrait.php
+++ b/src/TrashStorageTrait.php
@@ -8,7 +8,7 @@ trait TrashStorageTrait {
    * {@inheritdoc}
    */
   public function delete(array $entities) {
-    $field_name = $this->getEntityType()->getKey('deleted');
+    $field_name = 'deleted';
     $revisionable = $this->getEntityType()->isRevisionable();
 
     foreach ($entities as $entity) {
diff --git a/src/ViewsQueryAlter.php b/src/ViewsQueryAlter.php
index 126f2d70ef305875618401a6bc27c38299fee3dc..33576f766c24fabc45f208ee0578fa64cc9e5220 100644
--- a/src/ViewsQueryAlter.php
+++ b/src/ViewsQueryAlter.php
@@ -102,7 +102,7 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
 
     $entity_type_definitions = $this->entityTypeManager->getDefinitions();
     foreach ($entity_type_ids as $entity_type_id) {
-      if (in_array($entity_type_id, _trash_supported_entity_types(), TRUE)) {
+      if (\Drupal::service('trash.manager')->isEntityTypeEnabled($entity_type_definitions[$entity_type_id])) {
         $this->alterQueryForEntityType($query, $entity_type_definitions[$entity_type_id]);
       }
     }
@@ -120,7 +120,7 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
    *   The entity type definition.
    */
   protected function alterQueryForEntityType(Sql $query, EntityTypeInterface $entity_type) {
-    $table_mapping = $this->entityTypeManager->getStorage($entity_type->id())->getTableMapping(); 
+    $table_mapping = $this->entityTypeManager->getStorage($entity_type->id())->getTableMapping();
     assert($table_mapping instanceof DefaultTableMapping);
     $field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type->id());
 
@@ -129,8 +129,8 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
     // Try to find out whether any filter (normal or conditional filter) filters
     // by the delete column. In case it does opt out of adding a specific
     // delete column.
-    $deleted_table_name = $table_mapping->getFieldTableName($entity_type->getKey('deleted'));
-    $deleted_table_column = $table_mapping->getFieldColumnName($field_storage_definitions[$entity_type->getKey('deleted')], 'value');
+    $deleted_table_name = $table_mapping->getFieldTableName('deleted');
+    $deleted_table_column = $table_mapping->getFieldColumnName($field_storage_definitions['deleted'], 'value');
     foreach ($query->where as $group_index => $group) {
       if (!empty($group['conditions'])) {
         foreach ($group['conditions'] as $condition_index => $condition) {
diff --git a/tests/modules/trash_test/src/Entity/TrashTest.php b/tests/modules/trash_test/src/Entity/TrashTest.php
index c2b9ee37fab1b068b8d740d2352618dd67682814..03010d856e04064bd54234c28282628a2aa7d4fa 100644
--- a/tests/modules/trash_test/src/Entity/TrashTest.php
+++ b/tests/modules/trash_test/src/Entity/TrashTest.php
@@ -30,7 +30,6 @@ use Drupal\Core\Entity\ContentEntityBase;
  *     "revision" = "revision",
  *     "label" = "label",
  *     "uuid" = "uuid",
- *     "deleted" = "deleted",
  *   },
  *   links = {
  *     "canonical" = "/trash_test/{trash_test}",
@@ -41,15 +40,4 @@ use Drupal\Core\Entity\ContentEntityBase;
  */
 class TrashTest extends ContentEntityBase {
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getEntityKey($key) {
-    // Typically this protected method is used internally by entity classes and
-    // exposed publicly through more specific getter methods. So that test cases
-    // are able to set and access entity keys dynamically, update the visibility
-    // of this method to public.
-    return parent::getEntityKey($key);
-  }
-
 }
diff --git a/tests/src/Kernel/EntityQueryTest.php b/tests/src/Kernel/EntityQueryTest.php
index cdc92a9f69422d573c27d00944156e0f932c82ca..5e76ae887421d5326e705bc93f60d606002a40cf 100644
--- a/tests/src/Kernel/EntityQueryTest.php
+++ b/tests/src/Kernel/EntityQueryTest.php
@@ -67,7 +67,7 @@ class EntityQueryTest extends TrashKernelTestBase {
     $query = $entity_storage->getQuery();
     assert($query instanceof Query);
     $query->accessCheck(FALSE);
-    $query->condition($entity_type->getKey('deleted'), 0, '>');
+    $query->condition('deleted', 0, '>');
     $this->assertCount(3, $query->execute());
 
     // Try to fetch not deleted content.
@@ -81,7 +81,7 @@ class EntityQueryTest extends TrashKernelTestBase {
     $query = $entity_storage->getQuery();
     assert($query instanceof Query);
     $query->accessCheck(FALSE);
-    $query->condition($entity_type->getKey('deleted'), 0, '>');
+    $query->condition('deleted', 0, '>');
     $this->assertCount(3, $query->execute());
   }
 
diff --git a/tests/src/Kernel/TrashKernelTest.php b/tests/src/Kernel/TrashKernelTest.php
index 44336b4a3735405685e7d23ebdd9914ab56272f7..b29bfeea53583c356db3a58d1b28e6ee0859acbf 100644
--- a/tests/src/Kernel/TrashKernelTest.php
+++ b/tests/src/Kernel/TrashKernelTest.php
@@ -19,14 +19,14 @@ class TrashKernelTest extends TrashKernelTestBase {
     $entity->save();
 
     $this->assertNotNull(TrashTest::load($entity->id()));
-    $this->assertEquals(0, $entity->getEntityKey('deleted'));
+    $this->assertEquals(0, $entity->get('deleted')->value);
     $entity->delete();
 
     $entity = TrashTest::load($entity->id());
     assert($entity instanceof ContentEntityInterface);
 
     $this->assertNotNull($entity, "Ensure that deleting an entity doesn't actually deletes it.");
-    $this->assertEquals(\Drupal::time()->getRequestTime(), $entity->getEntityKey('deleted'));
+    $this->assertEquals(\Drupal::time()->getRequestTime(), $entity->get('deleted')->value);
   }
 
 }
diff --git a/tests/src/Kernel/TrashKernelTestBase.php b/tests/src/Kernel/TrashKernelTestBase.php
index cdd425f1615446a50fd86d6b78e0bb65143fa7cd..c49a7f14f9d750590a3a876efbf2ac3d76737d4f 100644
--- a/tests/src/Kernel/TrashKernelTestBase.php
+++ b/tests/src/Kernel/TrashKernelTestBase.php
@@ -22,8 +22,14 @@ abstract class TrashKernelTestBase extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->installConfig(['trash', 'trash_test']);
     $this->installEntitySchema('trash_test_entity');
-    $this->installConfig('trash_test');
+
+    $config = \Drupal::configFactory()->getEditable('trash.settings');
+    $enabled_entity_types = $config->get('enabled_entity_types');
+    $enabled_entity_types[] = 'trash_test_entity';
+    $config->set('enabled_entity_types', $enabled_entity_types);
+    $config->save();
   }
 
 }
diff --git a/trash.install b/trash.install
index 6b3aa2862e9b936207199d5edc28ead14089b1fe..6355a8f9d68537ebf165626a0d7ff6c00e19b8dc 100644
--- a/trash.install
+++ b/trash.install
@@ -4,40 +4,3 @@
  * @file
  * Install, update, and uninstall functions for the Trash module.
  */
-
-/**
- * Implements hook_module_preinstall().
- */
-function trash_module_preinstall($module) {
-  if ($module !== 'trash') {
-    return;
-  }
-
-  $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
-  foreach ($entity_definition_update_manager->getEntityTypes() as $entity_type) {
-    if (in_array($entity_type->id(), _trash_supported_entity_types(), TRUE)) {
-      $entity_keys = $entity_type->getKeys();
-      if (!isset($entity_keys['deleted'])) {
-        $entity_keys['deleted'] = 'deleted';
-
-        $entity_type->set('entity_keys', $entity_keys);
-        $entity_definition_update_manager->updateEntityType($entity_type);
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_uninstall().
- */
-function trash_uninstall() {
-  $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
-  foreach ($entity_definition_update_manager->getEntityTypes() as $entity_type) {
-    if (in_array($entity_type->id(), _trash_supported_entity_types(), TRUE)) {
-      $entity_keys = $entity_type->getKeys();
-      unset($entity_keys['deleted']);
-      $entity_type->set('entity_keys', $entity_keys);
-      $entity_definition_update_manager->updateEntityType($entity_type);
-    }
-  }
-}
diff --git a/trash.module b/trash.module
index d565a5f3713edd01dbd09374dd03802acf82cbff..c5b14c8c74bc1a1b17ed7b30e2b7b7a14f0c02ae 100644
--- a/trash.module
+++ b/trash.module
@@ -7,57 +7,23 @@ use Drupal\trash\ViewsQueryAlter;
 use Drupal\views\Plugin\views\query\QueryPluginBase;
 use Drupal\views\ViewExecutable;
 
-/**
- * Implements hook_entity_type_build().
- */
-function trash_entity_type_build(array &$entity_types) {
-  foreach ($entity_types as $entity_type) {
-    if (in_array($entity_type->id(), _trash_supported_entity_types(), TRUE)) {
-      // Add the required entity key.
-      $entity_keys = $entity_type->getKeys();
-      if (!isset($entity_keys['deleted'])) {
-        $entity_keys['deleted'] = 'deleted';
-
-        $entity_type->set('entity_keys', $entity_keys);
-      }
-    }
-  }
-}
-
 /**
  * Implements hook_entity_base_field_info().
  */
 function trash_entity_base_field_info(EntityTypeInterface $entity_type) {
   // Add the 'deleted' base field.
-  /** @var \Drupal\Core\Entity\ContentEntityType $entity_type */
-  if ($entity_type->hasKey('deleted')) {
-      $field_name = $entity_type->getKey('deleted');
-      $base_field_definitions[$field_name] = BaseFieldDefinition::create('timestamp')
-        ->setLabel(t('Deleted'))
-        ->setDescription(t('Time when the item got deleted'))
-        ->setInternal(TRUE)
-        ->setTranslatable(FALSE)
-        ->setRevisionable(TRUE);
+  if (\Drupal::service('trash.manager')->isEntityTypeEnabled($entity_type)) {
+    $base_field_definitions['deleted'] = BaseFieldDefinition::create('timestamp')
+      ->setLabel(t('Deleted'))
+      ->setDescription(t('Time when the item got deleted'))
+      ->setInternal(TRUE)
+      ->setTranslatable(FALSE)
+      ->setRevisionable(TRUE);
 
     return $base_field_definitions;
   }
 }
 
-/**
- * Returns the entity types supported by the Trash module.
- *
- * @return array
- */
-function _trash_supported_entity_types() {
-  // @todo How to expand this list?
-  return [
-//    'node',
-//    'media',
-//    'taxonomy_term',
-    'trash_test_entity',
-  ];
-}
-
 /**
  * Implements hook_views_query_alter().
  */
diff --git a/trash.services.yml b/trash.services.yml
index 45bbe31a8c3e27312ba3e17f5d65f3edbf9b09e4..dcbc7bc4d3195cef62e971206424287837513447 100644
--- a/trash.services.yml
+++ b/trash.services.yml
@@ -1,4 +1,14 @@
 services:
+  trash.manager:
+    class: Drupal\trash\TrashManager
+    arguments: ['@entity.definition_update_manager', '@entity.last_installed_schema.repository', '@config.factory']
+
+  trash.config_subscriber:
+    class: Drupal\trash\EventSubscriber\TrashConfigSubscriber
+    arguments: ['@entity_type.manager', '@trash.manager']
+    tags:
+      - { name: event_subscriber }
+
   trash.entity.query.sql:
     class: Drupal\trash\Entity\Query\Sql\QueryFactory
     public: false