diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8bf5a7ba5fd4b5838974427e677b2e2f62e025d1
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,43 @@
+################
+# GitLabCI template for Drupal projects.
+#
+# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification.
+# It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
+# As long as you include the project, ref and three files below, any future updates added by the Drupal Association will be used in your
+# pipelines automatically. However, you can modify this template if you have additional needs for your project.
+# The full documentation is on https://project.pages.drupalcode.org/gitlab_templates/
+################
+
+# For information on alternative values for 'ref' see https://project.pages.drupalcode.org/gitlab_templates/info/templates-version/
+# To test a Drupal 7 project, change the first include filename from .main.yml to .main-d7.yml
+include:
+  - project: $_GITLAB_TEMPLATES_REPO
+    ref: $_GITLAB_TEMPLATES_REF
+    file:
+      - '/includes/include.drupalci.main.yml'
+      - '/includes/include.drupalci.variables.yml'
+      - '/includes/include.drupalci.workflows.yml'
+#
+################
+# Pipeline configuration variables are defined with default values and descriptions in the file
+# https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.variables.yml
+# Uncomment the lines below if you want to override any of the variables. The following is just an example.
+################
+variables:
+  # @todo https://www.drupal.org/project/entity_reference_integrity/issues/3455209
+  OPT_IN_TEST_CURRENT: 0
+  OPT_IN_TEST_PREVIOUS_MAJOR: 1
+  OPT_IN_TEST_MAX_PHP: 1
+  _PHPUNIT_CONCURRENT: 1
+
+phpunit:
+  parallel:
+    matrix:
+      - _TARGET_DB_TYPE: 'mysql'
+        _TARGET_DB_VERSION: '8'
+      - _TARGET_DB_TYPE: 'pgsql'
+        _TARGET_DB_VERSION: '16'
+      - _TARGET_DB_TYPE: 'mariadb'
+        _TARGET_DB_VERSION: '10.6'
+      - _TARGET_DB_TYPE: 'sqlite'
+        _TARGET_DB_VERSION: '3'
diff --git a/entity_reference_integrity.info.yml b/entity_reference_integrity.info.yml
index 39b89c821f5f0f37cb2484684b14d58f1ddcb66a..599bc2424753d19d311aa189ec231146aa832a29 100644
--- a/entity_reference_integrity.info.yml
+++ b/entity_reference_integrity.info.yml
@@ -1,6 +1,6 @@
 name: Entity Reference Integrity
 description: Protect entities from being deleted if they are the target of an entity reference field.
-core_version_requirement: ^8.8 || ^9 || ^10
+core_version_requirement: ^10.2
 type: module
 
 package: Entity Reference Integrity
diff --git a/modules/entity_reference_integrity_enforce/entity_reference_integrity_enforce.info.yml b/modules/entity_reference_integrity_enforce/entity_reference_integrity_enforce.info.yml
index ce81670fa5bbd76f76a916c62e1efb666672e7f6..0695757168a9450405608c6e54bea9a5d45ef9b3 100644
--- a/modules/entity_reference_integrity_enforce/entity_reference_integrity_enforce.info.yml
+++ b/modules/entity_reference_integrity_enforce/entity_reference_integrity_enforce.info.yml
@@ -1,7 +1,7 @@
 name: Entity Reference Integrity Enforce
 description: Enforce reference integrity on entities.
 package: Entity Reference Integrity
-core_version_requirement: ^8.8 || ^9 || ^10
+core_version_requirement: ^10.2
 type: module
 
 dependencies:
diff --git a/modules/entity_reference_integrity_enforce/src/Form/SettingsForm.php b/modules/entity_reference_integrity_enforce/src/Form/SettingsForm.php
index 215a2f34c8cd91b7d4ac103ac5278d2cc501b015..d4fc9e697320f3fc532d181086e7565024b92d78 100644
--- a/modules/entity_reference_integrity_enforce/src/Form/SettingsForm.php
+++ b/modules/entity_reference_integrity_enforce/src/Form/SettingsForm.php
@@ -3,6 +3,8 @@
 namespace Drupal\entity_reference_integrity_enforce\Form;
 
 use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Config\TypedConfigManagerInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -21,10 +23,17 @@ class SettingsForm extends ConfigFormBase {
 
   /**
    * Create a SettingsForm.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   Defines the configuration object factory.
+   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
+   *   The typed config manager.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager service.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, $entity_type_definitions) {
-    parent::__construct($config_factory);
-    $this->entityTypeDefinitions = $entity_type_definitions;
+  public function __construct(ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, EntityTypeManagerInterface $entity_type_manager) {
+    parent::__construct($config_factory, $typed_config_manager);
+    $this->entityTypeDefinitions = $entity_type_manager->getDefinitions();
   }
 
   /**
@@ -33,7 +42,8 @@ class SettingsForm extends ConfigFormBase {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('config.factory'),
-      $container->get('entity_type.manager')->getDefinitions()
+      $container->get('config.typed'),
+      $container->get('entity_type.manager'),
     );
   }
 
diff --git a/modules/entity_reference_integrity_enforce/src/Plugin/Action/DeleteAction.php b/modules/entity_reference_integrity_enforce/src/Plugin/Action/DeleteAction.php
index 6b6adccd3feaae71d4112cdaad390e03dbcc3c88..b212355c47541371e14ad25dbf464a9c71d2083d 100644
--- a/modules/entity_reference_integrity_enforce/src/Plugin/Action/DeleteAction.php
+++ b/modules/entity_reference_integrity_enforce/src/Plugin/Action/DeleteAction.php
@@ -4,6 +4,7 @@ namespace Drupal\entity_reference_integrity_enforce\Plugin\Action;
 
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Action\Plugin\Action\DeleteAction as CoreDeleteAction;
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -17,10 +18,55 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  */
 class DeleteAction extends CoreDeleteAction {
 
+  /**
+   * The config factory service.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Constructs a new DeleteAction object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
+   *   The tempstore factory.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   Current user.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user, ConfigFactoryInterface $config_factory) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $temp_store_factory, $current_user);
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_type.manager'),
+      $container->get('tempstore.private'),
+      $container->get('current_user'),
+      $container->get('config.factory'),
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
-  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
     // First check if the account has access.
     $access = parent::access($object, $account, TRUE);
 
@@ -31,7 +77,7 @@ class DeleteAction extends CoreDeleteAction {
 
     // Check for dependent entities.
     $has_dependents = FALSE;
-    $enabled_entity_type_ids = \Drupal::config('entity_reference_integrity_enforce.settings')->get('enabled_entity_type_ids');
+    $enabled_entity_type_ids = $this->configFactory->get('entity_reference_integrity_enforce.settings')->get('enabled_entity_type_ids');
     if (in_array($object->getEntityTypeId(), $enabled_entity_type_ids, TRUE)) {
       $has_dependents = $this->entityTypeManager->getHandler($object->getEntityTypeId(), 'entity_reference_integrity')->hasDependents($object);
     }
diff --git a/modules/entity_reference_integrity_enforce/tests/src/Functional/JsonApiTest.php b/modules/entity_reference_integrity_enforce/tests/src/Functional/JsonApiTest.php
index 917ced00c13ba87ae104d95b77aacd690018017d..bdc939e37f186de901c6f467b5136fd234a71207 100644
--- a/modules/entity_reference_integrity_enforce/tests/src/Functional/JsonApiTest.php
+++ b/modules/entity_reference_integrity_enforce/tests/src/Functional/JsonApiTest.php
@@ -8,7 +8,7 @@ use Drupal\Core\Url;
 use Drupal\entity_reference_integrity\EntityReferenceIntegrityEntityHandler;
 use Drupal\node\Entity\NodeType;
 use Drupal\Tests\BrowserTestBase;
-use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
+use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait;
 use Drupal\Tests\jsonapi\Functional\JsonApiRequestTestTrait;
 use GuzzleHttp\RequestOptions;
 
@@ -19,7 +19,7 @@ use GuzzleHttp\RequestOptions;
  */
 class JsonApiTest extends BrowserTestBase {
 
-  use EntityReferenceTestTrait;
+  use EntityReferenceFieldCreationTrait;
   use JsonApiRequestTestTrait;
   use StringTranslationTrait;
 
@@ -151,7 +151,7 @@ class JsonApiTest extends BrowserTestBase {
     // Assert valid response body. Should be a JSONAPI response with errors.
     $response_data = Json::decode((string) $response->getBody());
     $this->assertArrayHasKey('errors', $response_data);
-    $this->assertEquals(1, sizeof($response_data['errors']));
+    $this->assertEquals(1, count($response_data['errors']));
     $this->assertArrayHasKey('status', $response_data['errors'][0]);
     $this->assertEquals('403', $response_data['errors'][0]['status']);
 
@@ -176,4 +176,5 @@ class JsonApiTest extends BrowserTestBase {
     $response = $this->request('DELETE', $node_url, $request_options);
     $this->assertEquals(204, $response->getStatusCode());
   }
+
 }
diff --git a/modules/entity_reference_integrity_enforce/tests/src/Kernel/DeleteActionTest.php b/modules/entity_reference_integrity_enforce/tests/src/Kernel/DeleteActionTest.php
index c4baa50bc5a9c2f7fbd7e770534393314fdc7e16..3b23a591589980c357893c9aaea8e0a3c70e35d4 100644
--- a/modules/entity_reference_integrity_enforce/tests/src/Kernel/DeleteActionTest.php
+++ b/modules/entity_reference_integrity_enforce/tests/src/Kernel/DeleteActionTest.php
@@ -6,7 +6,7 @@ use Drupal\entity_reference_integrity_enforce\Plugin\Action\DeleteAction;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
-use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
+use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait;
 use Drupal\user\Entity\User;
 
 /**
@@ -18,7 +18,7 @@ use Drupal\user\Entity\User;
  */
 class DeleteActionTest extends KernelTestBase {
 
-  use EntityReferenceTestTrait;
+  use EntityReferenceFieldCreationTrait;
 
   /**
    * {@inheritdoc}
@@ -107,9 +107,9 @@ class DeleteActionTest extends KernelTestBase {
 
     // Enable reference integrity for nodes.
     \Drupal::configFactory()
-           ->getEditable('entity_reference_integrity_enforce.settings')
-           ->set('enabled_entity_type_ids', ['node' => 'node'])
-           ->save();
+      ->getEditable('entity_reference_integrity_enforce.settings')
+      ->set('enabled_entity_type_ids', ['node' => 'node'])
+      ->save();
 
     // A test user is required for testing access.
     $this->testUser = User::create([
@@ -141,4 +141,5 @@ class DeleteActionTest extends KernelTestBase {
     $this->assertFalse($this->dependencyManager->hasDependents($this->referencedNode));
     $this->assertTrue($action->access($this->referencedNode, $this->testUser));
   }
+
 }
diff --git a/modules/entity_reference_integrity_enforce/tests/src/Kernel/EntityPredeleteHookTest.php b/modules/entity_reference_integrity_enforce/tests/src/Kernel/EntityPredeleteHookTest.php
index 4c237c3896e6f8202d138907a245c6c0ca651cd4..b9590ebbc7e3d82fa7a236e7d8e43a4122af2f86 100644
--- a/modules/entity_reference_integrity_enforce/tests/src/Kernel/EntityPredeleteHookTest.php
+++ b/modules/entity_reference_integrity_enforce/tests/src/Kernel/EntityPredeleteHookTest.php
@@ -23,22 +23,18 @@ class EntityPredeleteHookTest extends KernelTestBase {
 
   /**
    * Test the entity_predelete implementations.
-   *
-   * @requires function \Drupal\Core\Extension\ModuleHandlerInterface::hasImplementations
    */
   public function testHook() {
-    $this->assertTrue(\Drupal::moduleHandler()->hasImplementations('entity_predelete', 'entity_reference_integrity_enforce'));
-  }
 
-  /**
-   * Test the weight of entity_predelete implementations.
-   *
-   * @legacy
-   * @requires function \Drupal\Core\Extension\ModuleHandlerInterface::getImplementations
-   */
-  public function testHookWeightLegacy() {
-    $implementations = \Drupal::moduleHandler()->getImplementations('entity_predelete');
-    $this->assertEquals('entity_reference_integrity_enforce', array_shift($implementations));
+    // Get a list of all implementors of hook_entity_predelete().
+    $implementors = [];
+    \Drupal::moduleHandler()->invokeAllWith('entity_predelete', function (callable $hook, string $module) use (&$implementors) {
+      $implementors[] = $module;
+    });
+
+    // Confirm that our hook is the first in the list, and comment is second.
+    $this->assertEquals('entity_reference_integrity_enforce', reset($implementors));
+    $this->assertEquals('comment', next($implementors));
   }
 
 }
diff --git a/src/DependencyFieldMapGenerator.php b/src/DependencyFieldMapGenerator.php
index 19ee82ff6d837513af6485109b2f2865e0745f8c..01bc269effdb2fd870b11c893c5553d08d262072 100644
--- a/src/DependencyFieldMapGenerator.php
+++ b/src/DependencyFieldMapGenerator.php
@@ -90,7 +90,7 @@ class DependencyFieldMapGenerator implements DependencyFieldMapGeneratorInterfac
    */
   public function getReferencingFields($entity_type_id) {
     $map = $this->getReferentialFieldMap();
-    return isset($map[$entity_type_id]) ? $map[$entity_type_id] : [];
+    return $map[$entity_type_id] ?? [];
   }
 
 }
diff --git a/src/EntityReferenceDependencyManagerInterface.php b/src/EntityReferenceDependencyManagerInterface.php
index 532d0f20e47c435e5f88715d28bd1272f835114a..988a5ccf7997d7e5f164052f03d9cfe6db3f8cb1 100644
--- a/src/EntityReferenceDependencyManagerInterface.php
+++ b/src/EntityReferenceDependencyManagerInterface.php
@@ -10,7 +10,7 @@ use Drupal\Core\Entity\EntityInterface;
 interface EntityReferenceDependencyManagerInterface {
 
   /**
-   * Check if an entity has dependent entties.
+   * Check if an entity has dependent entities.
    *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   An entity.
@@ -51,6 +51,7 @@ interface EntityReferenceDependencyManagerInterface {
    *   Optional boolean to translate the string. Defaults to TRUE.
    *
    * @return string
+   *   The access denied reason string.
    */
   public static function getAccessDeniedReason(EntityInterface $entity, bool $translate = TRUE);
 
diff --git a/src/EntityReferenceIntegrityEntityHandler.php b/src/EntityReferenceIntegrityEntityHandler.php
index aeb5a4fc8dc64ad31eead5e6ca6adf619ea2c813..9185e9c4417616105eb8b395ff8fa83b004ac0db 100644
--- a/src/EntityReferenceIntegrityEntityHandler.php
+++ b/src/EntityReferenceIntegrityEntityHandler.php
@@ -103,7 +103,7 @@ class EntityReferenceIntegrityEntityHandler implements EntityHandlerInterface, E
    * source field list that match the given target ID.
    *
    * @param string $entity_type
-   *   The entityt type.
+   *   The entity type.
    * @param array $source_fields
    *   An array of source fields.
    * @param string|int $target_id