diff --git a/entityconnect.info.yml b/entityconnect.info.yml
index abd65dd..0245996 100644
--- a/entityconnect.info.yml
+++ b/entityconnect.info.yml
@@ -1,7 +1,7 @@
 name: Entity Connect
 type: module
 description: Allows for referenced entity to be created and edited from the entity reference field
-core_version_requirement: ^8.8 || ^9 || ^10 || ^11
+core_version_requirement: ^10.1 || ^11 || ^12
 package: Entity Connect
 configure: entityconnect.administration_form
 dependencies:
diff --git a/entityconnect.module b/entityconnect.module
index dff76f0..3edd94f 100644
--- a/entityconnect.module
+++ b/entityconnect.module
@@ -5,45 +5,17 @@
  * Contains entityconnect.module.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\entityconnect\Hook\EntityconnectHooks;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\entityconnect\Controller\EntityconnectController;
-use Drupal\entityconnect\EntityconnectFormUtils;
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function entityconnect_help($route_name, RouteMatchInterface $route_match) {
-  $module_path = \Drupal::service('extension.list.module')->getPath('entityconnect');
-  switch ($route_name) {
-    // Main module help for the entityconnect module.
-    case 'help.page.entityconnect':
-      $output = '';
-
-      $filepath = $module_path . '/README.md';
-      if (file_exists($filepath)) {
-        $readme = file_get_contents($filepath);
-      }
-      if (!isset($readme)) {
-        return NULL;
-      }
-      if (\Drupal::moduleHandler()->moduleExists('markdown')) {
-        $filters = \Drupal::moduleHandler()->invoke('markdown', 'filter_info');
-        $info = $filters['filter_markdown'];
-
-        if (function_exists($info['process callback'])) {
-          $output = $info['process callback']($readme, NULL);
-        }
-        else {
-          $output = '<pre>' . $readme . '</pre>';
-        }
-      }
-      else {
-        $output = '<pre>' . $readme . '</pre>';
-      }
-
-      return $output;
-  }
+  return \Drupal::service(EntityconnectHooks::class)->help($route_name, $route_match);
 }
 
 /**
@@ -60,66 +32,25 @@ function entityconnect_module_implements_alter(&$implementations, $hook) {
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function entityconnect_theme() {
-  $theme = [
-    // Entityconnect Entity add list page.
-    'entityconnect_entity_add_list' => [
-      'variables' => [
-        'items' => NULL,
-        'cache_id' => NULL,
-        'cancel_link' => NULL,
-      ],
-      'file' => 'templates/entityconnect.theme.inc',
-    ],
-  ];
-
-  return $theme;
+  return \Drupal::service(EntityconnectHooks::class)->theme();
 }
 
 /**
  * Implements hook_form_FORM_ID_alter().
  */
+#[LegacyHook]
 function entityconnect_form_field_config_edit_form_alter(array &$form, FormStateInterface $form_state) {
-  EntityconnectFormUtils::fieldConfigEditFormAlter($form, $form_state);
+  \Drupal::service(EntityconnectHooks::class)->formFieldConfigEditFormAlter($form, $form_state);
 }
 
 /**
  * Implements hook_form_alter().
  */
+#[LegacyHook]
 function entityconnect_form_alter(&$form, FormStateInterface $form_state, $form_id) {
-
-  // Get the cache from the id and set the form state if this is a child form.
-  $request = \Drupal::request();
-  if (!empty($request->query->get('build_cache_id'))) {
-    $cid = $request->query->get('build_cache_id');
-    $cache_data = \Drupal::getContainer()->get('entityconnect.cache')->get($cid);
-    if (!empty($request->query->get('child'))) {
-      $form_state->set('#entityconnect_child_form', [$cid => $cache_data]);
-    }
-    if (!empty($request->query->get('return')) && !empty($cache_data) && $cache_data['form']['#form_id'] == $form_id) {
-      $request->query->remove('build_cache_id');
-      EntityconnectFormUtils::returnFormAlter($form, $form_state, $cache_data);
-      \Drupal::getContainer()->get('entityconnect.cache')->delete($cid);
-    }
-  }
-
-  // If this form is a child form let's add alter for that purpose
-  // Note that we are doing this here because when we return to a form it gets
-  // rebuilt so this will get caught in the rebuilt.
-  if ($cache = $form_state->get('#entityconnect_child_form')) {
-    EntityconnectFormUtils::childFormAlter($form, $form_state, $form_id, key($cache));
-  }
-
-  // Adds entity connect buttons to any ref fields in the form.
-  EntityconnectFormUtils::entityFormAlter($form, $form_state);
-
-  if (isset($form['actions']['save_edit']) &&
-    $key = array_search('save_edit_form_submit_redirect', $form['actions']['save_edit']['#submit'])
-  ) {
-    // Fix an issue with removed query parameters.
-    unset($form['actions']['save_edit']['#submit'][$key]);
-    $form['actions']['save_edit']['#submit'][] = 'entityconnect_save_edit_submit_redirect';
-  }
+  \Drupal::service(EntityconnectHooks::class)->formAlter($form, $form_state, $form_id);
 }
 
 /**
@@ -145,13 +76,15 @@ function entityconnect_save_edit_submit_redirect(&$form, FormStateInterface $for
 /**
  * Implements hook_entityconnect_add_info().
  */
+#[LegacyHook]
 function entityconnect_entityconnect_add_info($cache_id, $entity_type, $acceptable_types) {
-  return EntityconnectController::addInfo($cache_id, $entity_type, $acceptable_types);
+  return \Drupal::service(EntityconnectHooks::class)->entityconnectAddInfo($cache_id, $entity_type, $acceptable_types);
 }
 
 /**
  * Implements hook_entityconnect_edit_info().
  */
+#[LegacyHook]
 function entityconnect_entityconnect_edit_info($cache_id, $entity_type, $target_id) {
-  return EntityconnectController::editInfo($cache_id, $entity_type, $target_id);
+  return \Drupal::service(EntityconnectHooks::class)->entityconnectEditInfo($cache_id, $entity_type, $target_id);
 }
diff --git a/entityconnect.services.yml b/entityconnect.services.yml
index ca7d7f1..d8aa880 100644
--- a/entityconnect.services.yml
+++ b/entityconnect.services.yml
@@ -8,3 +8,7 @@ services:
   entityconnect.cache:
       class: Drupal\entityconnect\EntityconnectCache
       arguments: ['@tempstore.private', '@session_manager', '@current_user']
+
+  Drupal\entityconnect\Hook\EntityconnectHooks:
+    class: Drupal\entityconnect\Hook\EntityconnectHooks
+    autowire: true
diff --git a/src/EntityconnectCache.php b/src/EntityconnectCache.php
index 5ce7a0c..578593e 100644
--- a/src/EntityconnectCache.php
+++ b/src/EntityconnectCache.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\entityconnect;
 
+use Drupal\Component\Utility\DeprecationHelper;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Session\SessionManager;
 use Drupal\Core\TempStore\PrivateTempStoreFactory;
@@ -52,7 +53,7 @@ class EntityconnectCache {
     $this->account = $account;
     // Start a manual session for anonymous users.
     if ($account->isAnonymous() && !isset($_SESSION['entityconnect_session'])) {
-      $_SESSION['entityconnect_session'] = TRUE;
+      DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.2.0', fn() => \Drupal::request()->getSession()->set('entityconnect_session', TRUE), fn() => $_SESSION['entityconnect_session'] = TRUE);
       $sessionManager->start();
     }
   }
diff --git a/src/Hook/EntityconnectHooks.php b/src/Hook/EntityconnectHooks.php
new file mode 100644
index 0000000..40e4d55
--- /dev/null
+++ b/src/Hook/EntityconnectHooks.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Drupal\entityconnect\Hook;
+
+use Drupal\entityconnect\Controller\EntityconnectController;
+use Drupal\entityconnect\EntityconnectFormUtils;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for entityconnect.
+ */
+class EntityconnectHooks {
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public function help($route_name, RouteMatchInterface $route_match) {
+    $module_path = \Drupal::service('extension.list.module')->getPath('entityconnect');
+    switch ($route_name) {
+      // Main module help for the entityconnect module.
+      case 'help.page.entityconnect':
+        $output = '';
+        $filepath = $module_path . '/README.md';
+        if (file_exists($filepath)) {
+          $readme = file_get_contents($filepath);
+        }
+        if (!isset($readme)) {
+          return NULL;
+        }
+        if (\Drupal::moduleHandler()->moduleExists('markdown')) {
+          $filters = \Drupal::moduleHandler()->invoke('markdown', 'filter_info');
+          $info = $filters['filter_markdown'];
+          if (function_exists($info['process callback'])) {
+            $output = $info['process callback']($readme, NULL);
+          }
+          else {
+            $output = '<pre>' . $readme . '</pre>';
+          }
+        }
+        else {
+          $output = '<pre>' . $readme . '</pre>';
+        }
+        return $output;
+    }
+  }
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public function theme() {
+    $theme = [
+          // Entityconnect Entity add list page.
+      'entityconnect_entity_add_list' => [
+        'variables' => [
+          'items' => NULL,
+          'cache_id' => NULL,
+          'cancel_link' => NULL,
+        ],
+        'file' => 'templates/entityconnect.theme.inc',
+      ],
+    ];
+    return $theme;
+  }
+
+  /**
+   * Implements hook_form_FORM_ID_alter().
+   */
+  #[Hook('form_field_config_edit_form_alter')]
+  public function formFieldConfigEditFormAlter(array &$form, FormStateInterface $form_state) {
+    EntityconnectFormUtils::fieldConfigEditFormAlter($form, $form_state);
+  }
+
+  /**
+   * Implements hook_form_alter().
+   */
+  #[Hook('form_alter')]
+  public function formAlter(&$form, FormStateInterface $form_state, $form_id) {
+    // Get the cache from the id and set the form state if this is a child form.
+    $request = \Drupal::request();
+    if (!empty($request->query->get('build_cache_id'))) {
+      $cid = $request->query->get('build_cache_id');
+      $cache_data = \Drupal::getContainer()->get('entityconnect.cache')->get($cid);
+      if (!empty($request->query->get('child'))) {
+        $form_state->set('#entityconnect_child_form', [
+          $cid => $cache_data,
+        ]);
+      }
+      if (!empty($request->query->get('return')) && !empty($cache_data) && $cache_data['form']['#form_id'] == $form_id) {
+        $request->query->remove('build_cache_id');
+        EntityconnectFormUtils::returnFormAlter($form, $form_state, $cache_data);
+        \Drupal::getContainer()->get('entityconnect.cache')->delete($cid);
+      }
+    }
+    // If this form is a child form let's add alter for that purpose
+    // Note that we are doing this here because when we return to a form it gets
+    // rebuilt so this will get caught in the rebuilt.
+    if ($cache = $form_state->get('#entityconnect_child_form')) {
+      EntityconnectFormUtils::childFormAlter($form, $form_state, $form_id, key($cache));
+    }
+    // Adds entity connect buttons to any ref fields in the form.
+    EntityconnectFormUtils::entityFormAlter($form, $form_state);
+    if (isset($form['actions']['save_edit']) && $key = array_search('save_edit_form_submit_redirect', $form['actions']['save_edit']['#submit'])) {
+      // Fix an issue with removed query parameters.
+      unset($form['actions']['save_edit']['#submit'][$key]);
+      $form['actions']['save_edit']['#submit'][] = 'entityconnect_save_edit_submit_redirect';
+    }
+  }
+
+  /**
+   * Implements hook_entityconnect_add_info().
+   */
+  #[Hook('entityconnect_add_info')]
+  public function entityconnectAddInfo($cache_id, $entity_type, $acceptable_types) {
+    return EntityconnectController::addInfo($cache_id, $entity_type, $acceptable_types);
+  }
+
+  /**
+   * Implements hook_entityconnect_edit_info().
+   */
+  #[Hook('entityconnect_edit_info')]
+  public function entityconnectEditInfo($cache_id, $entity_type, $target_id) {
+    return EntityconnectController::editInfo($cache_id, $entity_type, $target_id);
+  }
+
+}
diff --git a/tests/src/Functional/EntityconnectAddTest.php b/tests/src/Functional/EntityconnectAddTest.php
index 0852cae..d923504 100644
--- a/tests/src/Functional/EntityconnectAddTest.php
+++ b/tests/src/Functional/EntityconnectAddTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entityconnect\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Core\StringTranslation\StringTranslationTrait;
  *
  * @group entityconnect
  */
+#[Group('entityconnect')]
+#[RunTestsInSeparateProcesses]
 class EntityconnectAddTest extends EntityconnectTestBase {
   use StringTranslationTrait;
 
diff --git a/tests/src/Functional/EntityconnectAdminTest.php b/tests/src/Functional/EntityconnectAdminTest.php
index 0ec8149..6d0abb4 100644
--- a/tests/src/Functional/EntityconnectAdminTest.php
+++ b/tests/src/Functional/EntityconnectAdminTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entityconnect\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
 
@@ -10,6 +12,8 @@ use Drupal\Core\Url;
  *
  * @group entityconnect
  */
+#[Group('entityconnect')]
+#[RunTestsInSeparateProcesses]
 class EntityconnectAdminTest extends EntityconnectTestBase {
   use StringTranslationTrait;
 
diff --git a/tests/src/Functional/EntityconnectEditTest.php b/tests/src/Functional/EntityconnectEditTest.php
index 1d4abf7..e6dd6db 100644
--- a/tests/src/Functional/EntityconnectEditTest.php
+++ b/tests/src/Functional/EntityconnectEditTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entityconnect\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Core\StringTranslation\StringTranslationTrait;
  *
  * @group entityconnect
  */
+#[Group('entityconnect')]
+#[RunTestsInSeparateProcesses]
 class EntityconnectEditTest extends EntityconnectTestBase {
   use StringTranslationTrait;
 
diff --git a/tests/src/Functional/EntityconnectTestBase.php b/tests/src/Functional/EntityconnectTestBase.php
index 5f284cb..1f85baa 100644
--- a/tests/src/Functional/EntityconnectTestBase.php
+++ b/tests/src/Functional/EntityconnectTestBase.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\entityconnect\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\Tests\BrowserTestBase;
@@ -11,6 +12,7 @@ use Drupal\Tests\BrowserTestBase;
  *
  * @group entityconnect *
  */
+#[Group('entityconnect *')]
 abstract class EntityconnectTestBase extends BrowserTestBase {
 
   /**
