diff --git a/src/Hook/WorkbenchHooks.php b/src/Hook/WorkbenchHooks.php
new file mode 100644
index 0000000..20e0e9c
--- /dev/null
+++ b/src/Hook/WorkbenchHooks.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\workbench\Hook;
+
+use Drupal\workbench\Render\Element\WorkbenchToolbar;
+use Drupal\Core\Url;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Hook implementations for workbench.
+ */
+class WorkbenchHooks {
+  use StringTranslationTrait;
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public function help($route_name, RouteMatchInterface $route_match) {
+    switch ($route_name) {
+      case 'help.page.workbench':
+        $text = file_get_contents(dirname(__FILE__) . '/README.md');
+        if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
+          return workbench_parse_help($text);
+        }
+        else {
+          // Use the Markdown filter to render the README.
+          $filter_manager = \Drupal::service('plugin.manager.filter');
+          $settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
+          $config = [
+            'settings' => $settings,
+          ];
+          $filter = $filter_manager->createInstance('markdown', $config);
+          return $filter->process($text, 'en');
+        }
+    }
+    return NULL;
+  }
+
+  /**
+   * Implements hook_toolbar().
+   */
+  #[Hook('toolbar')]
+  public function toolbar() {
+    // The 'Workbench' tab is a simple link, with no corresponding tray.
+    $user = \Drupal::currentUser();
+    $items = [];
+    if ($user->hasPermission('access workbench')) {
+      $items['workbench'] = [
+        '#type' => 'toolbar_item',
+        'tab' => [
+          '#type' => 'link',
+          '#title' => $this->t('Workbench'),
+          '#url' => Url::fromRoute('workbench.content'),
+          '#attributes' => [
+            'title' => $this->t('My personal editorial workspace'),
+            'class' => [
+              'toolbar-icon',
+              'toolbar-icon-workbench-content-tab',
+            ],
+          ],
+        ],
+        'tray' => [
+          '#heading' => $this->t('Your Workbench'),
+          'workbench_toolbar' => [
+            '#pre_render' => [
+                        [
+                          WorkbenchToolbar::class,
+                          'preRenderTray',
+                        ],
+            ],
+          ],
+          '#type' => 'container',
+        ],
+        '#attached' => [
+          'library' => [
+            'workbench/workbench.toolbar',
+          ],
+        ],
+        '#weight' => -18,
+      ];
+    }
+    return $items;
+  }
+
+}
diff --git a/tests/modules/workbench_hooks_test/src/Hook/WorkbenchHooksTestHooks.php b/tests/modules/workbench_hooks_test/src/Hook/WorkbenchHooksTestHooks.php
new file mode 100644
index 0000000..f35dc33
--- /dev/null
+++ b/tests/modules/workbench_hooks_test/src/Hook/WorkbenchHooksTestHooks.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\workbench_hooks_test\Hook;
+
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for workbench_hooks_test.
+ */
+class WorkbenchHooksTestHooks {
+  /**
+   * @file
+   * Module hooks test.
+   */
+
+  /**
+   * Implements hook_workbench_block().
+   */
+  #[Hook('workbench_block')]
+  public function workbenchBlock() {
+    return [
+      'Test block content',
+    ];
+  }
+
+}
diff --git a/tests/modules/workbench_hooks_test/workbench_hooks_test.module b/tests/modules/workbench_hooks_test/workbench_hooks_test.module
index b34ff80..dffced3 100644
--- a/tests/modules/workbench_hooks_test/workbench_hooks_test.module
+++ b/tests/modules/workbench_hooks_test/workbench_hooks_test.module
@@ -1,5 +1,12 @@
 <?php
 
+/**
+ * @file
+ */
+
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\workbench_hooks_test\Hook\WorkbenchHooksTestHooks;
+
 /**
  * @file
  * Module hooks test.
@@ -8,8 +15,7 @@
 /**
  * Implements hook_workbench_block().
  */
+#[LegacyHook]
 function workbench_hooks_test_workbench_block() {
-  return [
-    'Test block content',
-  ];
+  return \Drupal::service(WorkbenchHooksTestHooks::class)->workbenchBlock();
 }
diff --git a/tests/modules/workbench_hooks_test/workbench_hooks_test.services.yml b/tests/modules/workbench_hooks_test/workbench_hooks_test.services.yml
new file mode 100644
index 0000000..32f6d26
--- /dev/null
+++ b/tests/modules/workbench_hooks_test/workbench_hooks_test.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\workbench_hooks_test\Hook\WorkbenchHooksTestHooks:
+    class: Drupal\workbench_hooks_test\Hook\WorkbenchHooksTestHooks
+    autowire: true
diff --git a/tests/src/Functional/WorkbenchBlockTest.php b/tests/src/Functional/WorkbenchBlockTest.php
index 6faacbc..b57f434 100644
--- a/tests/src/Functional/WorkbenchBlockTest.php
+++ b/tests/src/Functional/WorkbenchBlockTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\workbench\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\Access\AccessResultAllowed;
 use Drupal\Core\Access\AccessResultNeutral;
 use Drupal\Core\Session\AnonymousUserSession;
@@ -12,6 +14,8 @@ use Drupal\Tests\BrowserTestBase;
  *
  * @group workbench
  */
+#[Group('workbench')]
+#[RunTestsInSeparateProcesses]
 class WorkbenchBlockTest extends BrowserTestBase {
 
   /**
diff --git a/tests/src/Functional/WorkbenchInstallTest.php b/tests/src/Functional/WorkbenchInstallTest.php
index a017455..d06ec68 100644
--- a/tests/src/Functional/WorkbenchInstallTest.php
+++ b/tests/src/Functional/WorkbenchInstallTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\workbench\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Tests\BrowserTestBase;
  *
  * @group workbench
  */
+#[Group('workbench')]
+#[RunTestsInSeparateProcesses]
 class WorkbenchInstallTest extends BrowserTestBase {
 
   /**
diff --git a/tests/src/Functional/WorkbenchPermissionsTest.php b/tests/src/Functional/WorkbenchPermissionsTest.php
index 4ac6584..b4ad53f 100644
--- a/tests/src/Functional/WorkbenchPermissionsTest.php
+++ b/tests/src/Functional/WorkbenchPermissionsTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\workbench\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Tests\BrowserTestBase;
  *
  * @group workbench
  */
+#[Group('workbench')]
+#[RunTestsInSeparateProcesses]
 class WorkbenchPermissionsTest extends BrowserTestBase {
 
   /**
diff --git a/workbench.install b/workbench.install
index d1a2f65..1231d08 100644
--- a/workbench.install
+++ b/workbench.install
@@ -23,7 +23,7 @@ function workbench_update_8001(&$sandbox) {
   $config->set('description', 'The editorial workbench.');
   $config->set('langcode', 'en');
   $config->set('locked', TRUE);
-  $config->save(TRUE);
+  $config->save();
 }
 
 /**
@@ -37,5 +37,5 @@ function workbench_update_8002(&$sandbox) {
   $config->set('overview_main', 'workbench_recent_content:block_1');
   $config->set('edits_main', 'workbench_edited:embed_1');
   $config->set('all_main', 'workbench_recent_content:embed_1');
-  $config->save(TRUE);
+  $config->save();
 }
diff --git a/workbench.module b/workbench.module
index 6a1c307..372e891 100644
--- a/workbench.module
+++ b/workbench.module
@@ -5,70 +5,24 @@
  * Workbench module file.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\workbench\Hook\WorkbenchHooks;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Url;
-use Drupal\workbench\Render\Element\WorkbenchToolbar;
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function workbench_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.workbench':
-      $text = file_get_contents(dirname(__FILE__) . '/README.md');
-      if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
-        return workbench_parse_help($text);
-      }
-      else {
-        // Use the Markdown filter to render the README.
-        $filter_manager = \Drupal::service('plugin.manager.filter');
-        $settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
-        $config = ['settings' => $settings];
-        $filter = $filter_manager->createInstance('markdown', $config);
-        return $filter->process($text, 'en');
-      }
-  }
-  return NULL;
+  return \Drupal::service(WorkbenchHooks::class)->help($route_name, $route_match);
 }
 
 /**
  * Implements hook_toolbar().
  */
+#[LegacyHook]
 function workbench_toolbar() {
-  // The 'Workbench' tab is a simple link, with no corresponding tray.
-  $user = \Drupal::currentUser();
-
-  $items = [];
-  if ($user->hasPermission('access workbench')) {
-    $items['workbench'] = [
-      '#type' => 'toolbar_item',
-      'tab' => [
-        '#type' => 'link',
-        '#title' => t('Workbench'),
-        '#url' => Url::fromRoute('workbench.content'),
-        '#attributes' => [
-          'title' => t('My personal editorial workspace'),
-          'class' => ['toolbar-icon', 'toolbar-icon-workbench-content-tab'],
-        ],
-      ],
-      'tray' => [
-        '#heading' => t('Your Workbench'),
-        'workbench_toolbar' => [
-          '#pre_render' => [
-            [WorkbenchToolbar::class, 'preRenderTray'],
-          ],
-        ],
-        '#type' => 'container',
-      ],
-      '#attached' => [
-        'library' => [
-          'workbench/workbench.toolbar',
-        ],
-      ],
-      '#weight' => -18,
-    ];
-  }
-  return $items;
+  return \Drupal::service(WorkbenchHooks::class)->toolbar();
 }
 
 /**
diff --git a/workbench.services.yml b/workbench.services.yml
new file mode 100644
index 0000000..c7adacd
--- /dev/null
+++ b/workbench.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\workbench\Hook\WorkbenchHooks:
+    class: Drupal\workbench\Hook\WorkbenchHooks
+    autowire: true
