diff --git a/blocktheme.module b/blocktheme.module
index 8962b05..703143d 100644
--- a/blocktheme.module
+++ b/blocktheme.module
@@ -9,53 +9,33 @@
  * a tpl file to use as opposed to having to override the templates by block ID.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\blocktheme\Hook\BlockthemeHooks;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Link;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Url;
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function blocktheme_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.blocktheme':
-      $output = t('Allows the admin to define re-usable block templates that can be configured from block config screen.');
-      $items = [];
-      $items[] = Link::fromTextAndUrl(t('Block Theme'), Url::fromRoute('admin_blocktheme_config'));
-      $output .= '<h3>' . t('Block Theme administration pages') . '</h3>';
-      $item_list = [
-        '#theme' => 'item_list',
-        '#items' => $items,
-      ];
-      $output .= \Drupal::service('renderer')->render($item_list);
-      return $output;
-  }
+  return \Drupal::service(BlockthemeHooks::class)->help($route_name, $route_match);
 }
 
 /**
  * Implements hook_theme_suggestions_HOOK().
  */
+#[LegacyHook]
 function blocktheme_theme_suggestions_block(array $variables) {
-  $form_id = $variables['elements']['#id'];
-  if ($custom_block_theme = blocktheme_get_theme($form_id)) {
-    $template_name = 'block__blocktheme__' . str_replace('-', '_', $custom_block_theme);
-    return $template_name;
-  }
-
-  return NULL;
+  return \Drupal::service(BlockthemeHooks::class)->themeSuggestionsBlock($variables);
 }
 
 /**
  * Implements hook_preprocess_block().
  */
+#[LegacyHook]
 function blocktheme_preprocess_block(&$variables) {
-  $form_id = $variables['elements']['#id'];
-  if ($custom_block_vars = blocktheme_get_theme_vars($form_id)) {
-    $variables['blocktheme'] = blocktheme_get_theme($form_id);
-    $variables['blocktheme_vars'] = $custom_block_vars;
-    $variables['attributes']['class'][] = blocktheme_get_theme($form_id);
-  }
+  \Drupal::service(BlockthemeHooks::class)->preprocessBlock($variables);
 }
 
 /**
diff --git a/blocktheme.services.yml b/blocktheme.services.yml
new file mode 100644
index 0000000..f703a34
--- /dev/null
+++ b/blocktheme.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\blocktheme\Hook\BlockthemeHooks:
+    class: Drupal\blocktheme\Hook\BlockthemeHooks
+    autowire: true
diff --git a/src/Hook/BlockthemeHooks.php b/src/Hook/BlockthemeHooks.php
new file mode 100644
index 0000000..9c43856
--- /dev/null
+++ b/src/Hook/BlockthemeHooks.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Drupal\blocktheme\Hook;
+
+use Drupal\Core\Url;
+use Drupal\Core\Link;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Hook implementations for blocktheme.
+ */
+class BlockthemeHooks {
+  use StringTranslationTrait;
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public function help($route_name, RouteMatchInterface $route_match) {
+    switch ($route_name) {
+      case 'help.page.blocktheme':
+        $output = $this->t('Allows the admin to define re-usable block templates that can be configured from block config screen.');
+        $items = [];
+        $items[] = Link::fromTextAndUrl($this->t('Block Theme'), Url::fromRoute('admin_blocktheme_config'));
+        $output .= '<h3>' . $this->t('Block Theme administration pages') . '</h3>';
+        $item_list = [
+          '#theme' => 'item_list',
+          '#items' => $items,
+        ];
+        $output .= \Drupal::service('renderer')->render($item_list);
+        return $output;
+    }
+  }
+
+  /**
+   * Implements hook_theme_suggestions_HOOK().
+   */
+  #[Hook('theme_suggestions_block')]
+  public static function themeSuggestionsBlock(array $variables) {
+    $form_id = $variables['elements']['#id'];
+    if ($custom_block_theme = blocktheme_get_theme($form_id)) {
+      $template_name = 'block__blocktheme__' . str_replace('-', '_', $custom_block_theme);
+      return $template_name;
+    }
+    return NULL;
+  }
+
+  /**
+   * Implements hook_preprocess_block().
+   */
+  #[Hook('preprocess_block')]
+  public static function preprocessBlock(&$variables) {
+    $form_id = $variables['elements']['#id'];
+    if ($custom_block_vars = blocktheme_get_theme_vars($form_id)) {
+      $variables['blocktheme'] = blocktheme_get_theme($form_id);
+      $variables['blocktheme_vars'] = $custom_block_vars;
+      $variables['attributes']['class'][] = blocktheme_get_theme($form_id);
+    }
+  }
+
+}
