diff --git a/.cspell-project-words.txt b/.cspell-project-words.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7323ce4fdeb9dc84cba84d7526dd46e61c9a35c4
--- /dev/null
+++ b/.cspell-project-words.txt
@@ -0,0 +1,21 @@
+behaviour
+CONFIGNAME
+datasource
+dcterms
+Dfile
+Djava
+docconv
+docd
+DYLD
+escapeshellargs
+filefield
+getmessenger
+informations
+isexcluded
+MAMP
+pareview
+pdfminer
+pdfs
+pdftotext
+tika
+xmlstring
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7688cf0b255abbf785154c65b763090ce23f9cc5
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,40 @@
+################
+# 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:
+#   SKIP_ESLINT: '1'
+#   OPT_IN_TEST_NEXT_MAJOR: '1'
+#   _CURL_TEMPLATES_REF: 'main'
+
+#
+# Start custom overrides.
+# Based on https://git.drupalcode.org/project/keycdn/-/blob/8.x-1.x/.gitlab-ci.yml
+#
+
+variables:
+  OPT_IN_TEST_MAX_PHP: 1
+  OPT_IN_TEST_PREVIOUS_MINOR: 1
+  OPT_IN_TEST_NEXT_MINOR: 1
+  OPT_IN_TEST_NEXT_MAJOR: 1
diff --git a/assets/css/status.css b/assets/css/status.css
index 5c9358dd3090d60a2b51db98371d4778cc4a0de1..3bf26ee0e16543a200f8d0cb259c639208a94bc7 100644
--- a/assets/css/status.css
+++ b/assets/css/status.css
@@ -1,10 +1,10 @@
 .ok {
+  padding: 5px;
   border: 5px solid green;
   border-radius: 5px;
-  padding: 5px;
 }
 .error {
+  padding: 5px;
   border: 5px solid red;
   border-radius: 5px;
-  padding: 5px;
 }
diff --git a/composer.json b/composer.json
index af885dbe9891bfeabad4cf039cf5dff63e7f1900..6fcaf24f76371edb07c6fb84c505af7fe65d329f 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,19 @@
 {
-  "name": "drupal/search_api_attachments",
-  "description": "Extract and index file fields content.",
-  "type": "drupal-module",
-  "license": "GPL-2.0+"
+    "name": "drupal/search_api_attachments",
+    "description": "Search API Attachments.",
+    "type": "drupal-module",
+    "license": "GPL-2.0-or-later",
+    "minimum-stability": "dev",
+    "homepage": "https://drupal.org/project/search_api_attachments",
+    "support": {
+        "issues": "https://www.drupal.org/project/issues/search_api_attachments",
+        "source": "https://git.drupalcode.org/project/search_api_attachments"
+    },
+    "require": {
+        "drupal/core": "^10.3 || ^11",
+        "drupal/search_api": "^1"
+    },
+    "require-dev": {
+        "drupal/search_api_solr": "^4.3"
+    }
 }
diff --git a/search_api_attachments.info.yml b/search_api_attachments.info.yml
index 1ae71cf88b5b19168f794e9a9276686db9d1de9b..5dcdaed3a67a765aa82edef91c131de9f50ea712 100644
--- a/search_api_attachments.info.yml
+++ b/search_api_attachments.info.yml
@@ -1,7 +1,7 @@
 type: module
 name: 'Search API Attachments'
 description: 'Extract and index file fields content.'
-core_version_requirement: ^9 || ^10
+core_version_requirement: ^10.3 || ^11
 package: Search
 configure: search_api_attachments.admin_form
 dependencies:
diff --git a/search_api_attachments.module b/search_api_attachments.module
index e71d9492ace3d105e70c56ff7c35c2cff754c3c4..63d9a8d340b682b9a543fc9157fcf8c7be9f52ad 100644
--- a/search_api_attachments.module
+++ b/search_api_attachments.module
@@ -5,8 +5,9 @@
  * Implement hooks and help functions to delete extracted files cache content.
  */
 
-use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\ContentEntityType;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\file\Entity\File;
 use Drupal\search_api\Entity\Index;
@@ -113,8 +114,8 @@ function search_api_attachments_entity_extra_field_info() {
  * Implements hook_entity_view().
  */
 function search_api_attachments_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
-  $attacments_component = $display->getComponent('search_api_attachments');
-  if ($attacments_component !== NULL) {
+  $attachments_component = $display->getComponent('search_api_attachments');
+  if ($attachments_component !== NULL) {
     $indexes = Index::loadMultiple();
     foreach ($indexes as $index) {
       $index_fields = array_keys($index->getFields());
diff --git a/search_api_attachments.permissions.yml b/search_api_attachments.permissions.yml
index f9aefd62b5cf32bad15e5885bceceb1423db90b2..1cfd30fa506b5630ed19f70f1f9aab1682576dca 100644
--- a/search_api_attachments.permissions.yml
+++ b/search_api_attachments.permissions.yml
@@ -1,4 +1,4 @@
 'administer search_api_attachments':
   title: 'Administer Search API Attachments'
-  description: 'Configure the commands used by Search API Attachments to exectract data.'
+  description: 'Configure the commands used by Search API Attachments to extract data.'
   restrict access: TRUE
diff --git a/src/Form/TextExtractorFormSettings.php b/src/Form/TextExtractorFormSettings.php
index 2eb2e7c73d38a491a739514778085bef0151eeef..7333ce4ee5524a7b6952ec6d0bdcbdc7cd01b39e 100644
--- a/src/Form/TextExtractorFormSettings.php
+++ b/src/Form/TextExtractorFormSettings.php
@@ -2,16 +2,12 @@
 
 namespace Drupal\search_api_attachments\Form;
 
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Component\Utility\Html;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
 use Drupal\file\Entity\File;
-use Drupal\search_api_attachments\TextExtractorPluginManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Configuration form.
@@ -44,26 +40,15 @@ class TextExtractorFormSettings extends ConfigFormBase {
    */
   protected $moduleExtensionList;
 
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(ConfigFactoryInterface $config_factory, TextExtractorPluginManager $text_extractor_plugin_manager, EntityTypeManagerInterface $entity_type_manager, ModuleExtensionList $module_extension_list) {
-    parent::__construct($config_factory);
-    $this->textExtractorPluginManager = $text_extractor_plugin_manager;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->moduleExtensionList = $module_extension_list;
-  }
-
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('config.factory'),
-      $container->get('plugin.manager.search_api_attachments.text_extractor'),
-      $container->get('entity_type.manager'),
-      $container->get('extension.list.module'),
-    );
+    $instance = parent::create($container);
+    $instance->textExtractorPluginManager = $container->get('plugin.manager.search_api_attachments.text_extractor');
+    $instance->entityTypeManager = $container->get('entity_type.manager');
+    $instance->moduleExtensionList = $container->get('extension.list.module');
+    return $instance;
   }
 
   /**
@@ -98,7 +83,7 @@ class TextExtractorFormSettings extends ConfigFormBase {
       '#ajax' => [
         'callback' => [get_class($this), 'buildAjaxTextExtractorConfigForm'],
         'wrapper' => 'search-api-attachments-extractor-config-form',
-        'method' => 'replace',
+        'method' => 'replaceWith',
         'effect' => 'fade',
       ],
     ];
@@ -167,7 +152,7 @@ class TextExtractorFormSettings extends ConfigFormBase {
     $config = $this->configFactory()->getEditable(static::CONFIGNAME);
     // Set the extraction method variable.
     $config->set('extraction_method', $extractor_plugin_id);
-    // Set the redad text files directly option.
+    // Set the read text files directly option.
     $config->set('read_text_files_directly', $form_state->getValue('read_text_files_directly'));
     // Set the preserving cache option.
     $config->set('preserve_cache', $form_state->getValue('preserve_cache'));
@@ -186,7 +171,7 @@ class TextExtractorFormSettings extends ConfigFormBase {
     $file->delete();
     if (empty($extracted_data)) {
       if (empty($error)) {
-        $error = $this->t('No error message was catched');
+        $error = $this->t('No error message was caught');
       }
       $data = [
         'message' => $this->t("Unfortunately, the extraction doesn't seem to work with this configuration! (@error)", ['@error' => $error]),
@@ -374,7 +359,7 @@ class TextExtractorFormSettings extends ConfigFormBase {
    *   The text extractor plugin manager.
    */
   protected function getTextExtractorPluginManager() {
-    return $this->textExtractorPluginManager ?: \Drupal::service('plugin.manager.search_api_attachments.text_extractor');
+    return $this->textExtractorPluginManager;
   }
 
 }
diff --git a/src/Plugin/Field/FieldFormatter/ExtractedText.php b/src/Plugin/Field/FieldFormatter/ExtractedText.php
index ba5bf7d45438aabfeb72b8c6b8dbd4af58b22d1b..4f4826096b5d0c7b9df67f5fdaf6422b4cdf2009 100644
--- a/src/Plugin/Field/FieldFormatter/ExtractedText.php
+++ b/src/Plugin/Field/FieldFormatter/ExtractedText.php
@@ -2,19 +2,15 @@
 
 namespace Drupal\search_api_attachments\Plugin\Field\FieldFormatter;
 
-use Drupal\Core\Config\Config;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\file\Entity\File;
 use Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase;
-use Drupal\search_api\Processor\ProcessorPluginManager;
 use Drupal\search_api_attachments\ExtractFileValidator;
 use Drupal\search_api_attachments\Plugin\search_api\processor\FilesExtractor;
-use Drupal\search_api_attachments\TextExtractorPluginManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -96,26 +92,10 @@ class ExtractedText extends FileFormatterBase implements ContainerFactoryPluginI
    *   The view mode.
    * @param array $thirdPartySettings
    *   The third party settings.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
-   *   The module handler.
-   * @param \Drupal\search_api\Processor\ProcessorPluginManager $processorPluginManager
-   *   The processor plugin manager.
-   * @param \Drupal\search_api_attachments\TextExtractorPluginManager $textExtractorPluginManager
-   *   The text extractor plugin manager.
-   * @param \Drupal\Core\Config\Config $config
-   *   The configuration.
-   * @param \Drupal\search_api_attachments\ExtractFileValidator $extractFileValidator
-   *   The extract file validator.
    */
-  public function __construct($pluginId, $pluginDefinition, FieldDefinitionInterface $fieldDefinition, array $settings, $label, $viewMode, array $thirdPartySettings, ModuleHandlerInterface $moduleHandler, ProcessorPluginManager $processorPluginManager, TextExtractorPluginManager $textExtractorPluginManager, Config $config, ExtractFileValidator $extractFileValidator) {
+  public function __construct($pluginId, $pluginDefinition, FieldDefinitionInterface $fieldDefinition, array $settings, $label, $viewMode, array $thirdPartySettings) {
     parent::__construct($pluginId, $pluginDefinition, $fieldDefinition, $settings, $label, $viewMode, $thirdPartySettings);
 
-    $this->moduleHandler = $moduleHandler;
-    $this->processorPluginManager = $processorPluginManager;
-    $this->textExtractorPluginManager = $textExtractorPluginManager;
-    $this->config = $config;
-    $this->extractFileValidator = $extractFileValidator;
-
     $extractorPluginId = $this
       ->config
       ->get('extraction_method');
@@ -129,27 +109,19 @@ class ExtractedText extends FileFormatterBase implements ContainerFactoryPluginI
     $this->extractor = $this
       ->processorPluginManager
       ->createInstance('file_attachments');
-    ;
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $pluginDefinition) {
-    return new static(
-      $plugin_id,
-      $pluginDefinition,
-      $configuration['field_definition'],
-      $configuration['settings'],
-      $configuration['label'],
-      $configuration['view_mode'],
-      $configuration['third_party_settings'],
-      $container->get('module_handler'),
-      $container->get('plugin.manager.search_api.processor'),
-      $container->get('plugin.manager.search_api_attachments.text_extractor'),
-      $container->get('config.factory')->get(FilesExtractor::CONFIGNAME),
-      $container->get('search_api_attachments.extract_file_validator')
-    );
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->moduleHandler = $container->get('module_handler');
+    $instance->processorPluginManager = $container->get('plugin.manager.search_api.processor');
+    $instance->textExtractorPluginManager = $container->get('plugin.manager.search_api_attachments.text_extractor');
+    $instance->config = $container->get('config.factory')->get(FilesExtractor::CONFIGNAME);
+    $instance->extractFileValidator = $container->get('search_api_attachments.extract_file_validator');
+    return $instance;
   }
 
   /**
diff --git a/src/Plugin/QueueWorker/ExtractorQueue.php b/src/Plugin/QueueWorker/ExtractorQueue.php
index 4b3eaf26443dc7d724028f03f7a04e383527a170..621ee5d4ae569673af836e412611fdcdbb2710fc 100644
--- a/src/Plugin/QueueWorker/ExtractorQueue.php
+++ b/src/Plugin/QueueWorker/ExtractorQueue.php
@@ -2,18 +2,13 @@
 
 namespace Drupal\search_api_attachments\Plugin\QueueWorker;
 
-use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\TranslatableInterface;
-use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Queue\QueueWorkerBase;
 use Drupal\search_api\Plugin\search_api\datasource\ContentEntity;
 use Drupal\search_api_attachments\Plugin\search_api\processor\FilesExtractor;
-use Drupal\search_api_attachments\TextExtractorPluginManager;
-use Psr\Log\LoggerInterface;
 use Psr\Log\LogLevel;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
 
 /**
  * Processes Tasks for Search API Attachments.
@@ -26,6 +21,13 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
  */
 class ExtractorQueue extends QueueWorkerBase implements ContainerFactoryPluginInterface {
 
+  /**
+   * Files extractor config.
+   *
+   * @var \Drupal\Core\Config\Config
+   */
+  protected $config;
+
   /**
    * Text extractor service.
    *
@@ -62,31 +64,25 @@ class ExtractorQueue extends QueueWorkerBase implements ContainerFactoryPluginIn
   protected $moduleHandler;
 
   /**
-   * {@inheritdoc}
+   * The queue.
+   *
+   * @var \Drupal\Core\Queue\QueueInterface
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, TextExtractorPluginManager $text_extractor_plugin_manager, EntityTypeManagerInterface $entity_type_manager, KeyValueFactoryInterface $key_value, LoggerInterface $logger, ModuleHandlerInterface $module_handler) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->textExtractorPluginManager = $text_extractor_plugin_manager;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->keyValue = $key_value;
-    $this->logger = $logger;
-    $this->moduleHandler = $module_handler;
-  }
+  protected $queue;
 
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('plugin.manager.search_api_attachments.text_extractor'),
-      $container->get('entity_type.manager'),
-      $container->get('keyvalue'),
-      $container->get('logger.channel.search_api_attachments'),
-      $container->get('module_handler')
-    );
+    $instance = new static($configuration, $plugin_id, $plugin_definition);
+    $instance->config = $container->get('config.factory')->get(FilesExtractor::CONFIGNAME);
+    $instance->textExtractorPluginManager = $container->get('plugin.manager.search_api_attachments.text_extractor');
+    $instance->entityTypeManager = $container->get('entity_type.manager');
+    $instance->keyValue = $container->get('keyvalue');
+    $instance->logger = $container->get('logger.channel.search_api_attachments');
+    $instance->moduleHandler = $container->get('module_handler');
+    $instance->queue = $container->get('queue')->get('search_api_attachments');
+    return $instance;
   }
 
   /**
@@ -99,9 +95,8 @@ class ExtractorQueue extends QueueWorkerBase implements ContainerFactoryPluginIn
    */
   protected function getExtractorPlugin() {
     // Get extractor configuration.
-    $config = \Drupal::config(FilesExtractor::CONFIGNAME);
-    $extractor_plugin_id = $config->get('extraction_method');
-    $configuration = $config->get($extractor_plugin_id . '_configuration');
+    $extractor_plugin_id = $this->config->get('extraction_method');
+    $configuration = $this->config->get($extractor_plugin_id . '_configuration');
 
     // Get extractor plugin.
     return $this->textExtractorPluginManager->createInstance($extractor_plugin_id, $configuration);
@@ -166,7 +161,7 @@ class ExtractorQueue extends QueueWorkerBase implements ContainerFactoryPluginIn
     catch (\Exception $exception) {
       if ($data->extract_attempts < 5) {
         $data->extract_attempts++;
-        \Drupal::queue('search_api_attachments')->createItem($data);
+        $this->queue->createItem($data);
       }
       else {
         $message_params = [
diff --git a/src/Plugin/search_api/processor/FilesExtractor.php b/src/Plugin/search_api/processor/FilesExtractor.php
index cdbcb2d7f9b3dc8c6558cf345987d112ca09b75a..1e140a20d8ed1d55c299320357e748f7eb0266fd 100644
--- a/src/Plugin/search_api/processor/FilesExtractor.php
+++ b/src/Plugin/search_api/processor/FilesExtractor.php
@@ -5,13 +5,9 @@ namespace Drupal\search_api_attachments\Plugin\search_api\processor;
 use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 use Drupal\Component\Utility\Bytes;
-use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\Utility\Error;
 use Drupal\file\Entity\File;
@@ -20,11 +16,8 @@ use Drupal\search_api\Datasource\DatasourceInterface;
 use Drupal\search_api\Item\ItemInterface;
 use Drupal\search_api\Processor\ProcessorPluginBase;
 use Drupal\search_api\Processor\ProcessorProperty;
-use Drupal\search_api\Utility\FieldsHelperInterface;
 use Drupal\search_api_attachments\ExtractFileValidator;
 use Drupal\search_api_attachments\TextExtractorPluginInterface;
-use Drupal\search_api_attachments\TextExtractorPluginManager;
-use Psr\Log\LoggerInterface;
 use Psr\Log\LogLevel;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -121,37 +114,35 @@ class FilesExtractor extends ProcessorPluginBase implements PluginFormInterface
   protected $logger;
 
   /**
-   * {@inheritdoc}
+   * The lock service.
+   *
+   * @var \Drupal\Core\Lock\LockBackendInterface
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, TextExtractorPluginManager $text_extractor_plugin_manager, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, KeyValueFactoryInterface $key_value, ModuleHandlerInterface $module_handler, FieldsHelperInterface $field_helper, ExtractFileValidator $extractFileValidator, LoggerInterface $logger) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->textExtractorPluginManager = $text_extractor_plugin_manager;
-    $this->configFactory = $config_factory;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->keyValue = $key_value;
-    $this->moduleHandler = $module_handler;
-    $this->fieldHelper = $field_helper;
-    $this->extractFileValidator = $extractFileValidator;
-    $this->logger = $logger;
-  }
+  protected $lock;
+
+  /**
+   * The queue.
+   *
+   * @var \Drupal\Core\Queue\QueueInterface
+   */
+  protected $queue;
 
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-        $configuration,
-        $plugin_id,
-        $plugin_definition,
-        $container->get('plugin.manager.search_api_attachments.text_extractor'),
-        $container->get('config.factory'),
-        $container->get('entity_type.manager'),
-        $container->get('keyvalue'),
-        $container->get('module_handler'),
-        $container->get('search_api.fields_helper'),
-        $container->get('search_api_attachments.extract_file_validator'),
-        $container->get('logger.channel.search_api_attachments')
-    );
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->textExtractorPluginManager = $container->get('plugin.manager.search_api_attachments.text_extractor');
+    $instance->configFactory = $container->get('config.factory');
+    $instance->entityTypeManager = $container->get('entity_type.manager');
+    $instance->keyValue = $container->get('keyvalue');
+    $instance->moduleHandler = $container->get('module_handler');
+    $instance->fieldHelper = $container->get('search_api.fields_helper');
+    $instance->extractFileValidator = $container->get('search_api_attachments.extract_file_validator');
+    $instance->logger = $container->get('logger.channel.search_api_attachments');
+    $instance->lock = $container->get('lock');
+    $instance->queue = $container->get('queue')->get('search_api_attachments');
+    return $instance;
   }
 
   /**
@@ -343,21 +334,20 @@ class FilesExtractor extends ProcessorPluginBase implements PluginFormInterface
    */
   private function queueItem(EntityInterface $entity, File $file) {
 
-    if (\Drupal::lock()->acquire(static::FALLBACK_QUEUE_LOCK)) {
+    if ($this->lock->acquire(static::FALLBACK_QUEUE_LOCK)) {
       $queued_file_collection = $this->keyValue->get(static::FALLBACK_QUEUE_KV);
       $queued_files = $queued_file_collection->get($file->id());
       $queued_files[$entity->getEntityTypeId()][$entity->id()] = TRUE;
       $queued_file_collection->set($file->id(), $queued_files);
-      \Drupal::lock()->release(static::FALLBACK_QUEUE_LOCK);
+      $this->lock->release(static::FALLBACK_QUEUE_LOCK);
 
       // Add file to queue.
-      $queue = \Drupal::queue('search_api_attachments');
       $item = new \stdClass();
       $item->fid = $file->id();
       $item->entity_id = $entity->id();
       $item->entity_type = $entity->getEntityTypeId();
       $item->extract_attempts = 1;
-      $queue->createItem($item);
+      $this->queue->createItem($item);
 
       $this->logger->log(LogLevel::INFO, 'File added to the queue for text extraction @file_id for @entity_type @entity_id.', [
         '@file_id' => $file->id(),
@@ -512,12 +502,8 @@ class FilesExtractor extends ProcessorPluginBase implements PluginFormInterface
                       }
                     }
                   }
-                  catch (InvalidPluginDefinitionException $e) {
-                    watchdog_exception('search_api_attachments', $e);
-                    continue;
-                  }
-                  catch (PluginNotFoundException $e) {
-                    watchdog_exception('search_api_attachments', $e);
+                  catch (InvalidPluginDefinitionException | PluginNotFoundException $e) {
+                    Error::logException($this->logger, $e);
                     continue;
                   }
                 }
diff --git a/src/Plugin/search_api_attachments/DocconvExtractor.php b/src/Plugin/search_api_attachments/DocconvExtractor.php
index 62405cee0ac1d4e72e03310cd50dd2e24305b39c..0f3c5c58a882a37c6d05bcc228ea571eab6ec667 100644
--- a/src/Plugin/search_api_attachments/DocconvExtractor.php
+++ b/src/Plugin/search_api_attachments/DocconvExtractor.php
@@ -38,7 +38,7 @@ class DocconvExtractor extends TextExtractorPluginBase {
 
     $output = shell_exec($cmd);
     if (is_null($output)) {
-      throw new \Exception('Docconv Exctractor is not available.');
+      throw new \Exception('Docconv Extractor is not available.');
     }
     return $output;
   }
diff --git a/src/Plugin/search_api_attachments/PdftotextExtractor.php b/src/Plugin/search_api_attachments/PdftotextExtractor.php
index 43decece65e2c49d331a330c8dce6c487e50aac3..bfdad946381a438b8eb58bb8f122a806de07d6f5 100644
--- a/src/Plugin/search_api_attachments/PdftotextExtractor.php
+++ b/src/Plugin/search_api_attachments/PdftotextExtractor.php
@@ -3,8 +3,8 @@
 namespace Drupal\search_api_attachments\Plugin\search_api_attachments;
 
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\search_api_attachments\TextExtractorPluginBase;
 use Drupal\file\Entity\File;
+use Drupal\search_api_attachments\TextExtractorPluginBase;
 
 /**
  * Provides pdftotext extractor.
@@ -47,7 +47,7 @@ class PdftotextExtractor extends TextExtractorPluginBase {
       shell_exec("LANG=en_US.utf-8");
       $output = shell_exec($cmd);
       if (is_null($output)) {
-        throw new \Exception('Pdftotext Exctractor is not available.');
+        throw new \Exception('Pdftotext Extractor is not available.');
       }
       return $output;
     }
diff --git a/src/Plugin/search_api_attachments/PythonPdf2txtExtractor.php b/src/Plugin/search_api_attachments/PythonPdf2txtExtractor.php
index e7bed122bf876b136228341209bd330b9a9f8a84..2154497889bc099982cee4ec4d34e4d518cbcef1 100644
--- a/src/Plugin/search_api_attachments/PythonPdf2txtExtractor.php
+++ b/src/Plugin/search_api_attachments/PythonPdf2txtExtractor.php
@@ -3,8 +3,8 @@
 namespace Drupal\search_api_attachments\Plugin\search_api_attachments;
 
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\search_api_attachments\TextExtractorPluginBase;
 use Drupal\file\Entity\File;
+use Drupal\search_api_attachments\TextExtractorPluginBase;
 
 /**
  * Provides python pdf2text extractor.
@@ -46,7 +46,7 @@ class PythonPdf2txtExtractor extends TextExtractorPluginBase {
       shell_exec("LANG=en_US.utf-8");
       $output = shell_exec($cmd);
       if (is_null($output)) {
-        throw new \Exception('Python Pdf2txt Exctractor is not available.');
+        throw new \Exception('Python Pdf2txt Extractor is not available.');
       }
       return $output;
     }
diff --git a/src/Plugin/search_api_attachments/SolrExtractor.php b/src/Plugin/search_api_attachments/SolrExtractor.php
index 0f8d854dcbb9d72fca557fe13a85ed07d2fdec2a..eba961778724bf21ba308359819fb230a19e5264 100644
--- a/src/Plugin/search_api_attachments/SolrExtractor.php
+++ b/src/Plugin/search_api_attachments/SolrExtractor.php
@@ -2,17 +2,11 @@
 
 namespace Drupal\search_api_attachments\Plugin\search_api_attachments;
 
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Messenger\MessengerInterface;
-use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
+use Drupal\file\Entity\File;
 use Drupal\search_api_attachments\TextExtractorPluginBase;
 use Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\Mime\MimeTypeGuesserInterface;
-use Drupal\file\Entity\File;
 
 /**
  * Provides solr extractor.
@@ -32,21 +26,13 @@ class SolrExtractor extends TextExtractorPluginBase {
    */
   protected $entityTypeManager;
 
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactoryInterface $config_factory, StreamWrapperManagerInterface $stream_wrapper_manager, MimeTypeGuesserInterface $mime_type_guesser, MessengerInterface $messenger, FileSystemInterface $file_system, EntityTypeManagerInterface $entity_type_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $config_factory, $stream_wrapper_manager, $mime_type_guesser, $messenger, $file_system);
-    $this->entityTypeManager = $entity_type_manager;
-  }
-
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-        $configuration, $plugin_id, $plugin_definition, $container->get('config.factory'), $container->get('stream_wrapper_manager'), $container->get('file.mime_type.guesser'), $container->get('messenger'), $container->get('file_system'), $container->get('entity_type.manager')
-    );
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->entityTypeManager = $container->get('entity_type.manager');
+    return $instance;
   }
 
   /**
@@ -72,7 +58,7 @@ class SolrExtractor extends TextExtractorPluginBase {
     $backend = $server->getBackend();
 
     if (!$backend->isAvailable()) {
-      throw new \Exception('Solr Exctractor is not available.');
+      throw new \Exception('Solr Extractor is not available.');
     }
 
     // Extract the content.
diff --git a/src/Plugin/search_api_attachments/TikaExtractor.php b/src/Plugin/search_api_attachments/TikaExtractor.php
index 45ed18ab4d0b43976fe69cec61ac28305f9499ad..83d0664129349babcf5108e87634131ba63ef256 100644
--- a/src/Plugin/search_api_attachments/TikaExtractor.php
+++ b/src/Plugin/search_api_attachments/TikaExtractor.php
@@ -3,8 +3,8 @@
 namespace Drupal\search_api_attachments\Plugin\search_api_attachments;
 
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\search_api_attachments\TextExtractorPluginBase;
 use Drupal\file\Entity\File;
+use Drupal\search_api_attachments\TextExtractorPluginBase;
 
 /**
  * Provides tika extractor.
@@ -36,7 +36,7 @@ class TikaExtractor extends TextExtractorPluginBase {
     // So temporarily set the locale to UTF-8 if available so that the filepath
     // remains valid.
     // Attempt to use en_US.UTF-8 first, and fallback to C.UTF-8, since
-    // en_US.UTF-8 is more widespread, while C.UTF-8 may be present otherwwise.
+    // en_US.UTF-8 is more widespread, while C.UTF-8 may be present otherwise.
     $backup_locale = setlocale(LC_CTYPE, '0');
     $preferred_locales = ['en_US.UTF-8', 'C.UTF-8'];
     $new_locale = setlocale(LC_CTYPE, $preferred_locales) ?: $backup_locale;
diff --git a/src/Plugin/search_api_attachments/TikaServerExtractor.php b/src/Plugin/search_api_attachments/TikaServerExtractor.php
index 47571779065de77fb87b69dbe38a393efc0c4f32..b82a930e1f4b10b2fb1f65bdefd7ea58fb3f1101 100644
--- a/src/Plugin/search_api_attachments/TikaServerExtractor.php
+++ b/src/Plugin/search_api_attachments/TikaServerExtractor.php
@@ -2,16 +2,10 @@
 
 namespace Drupal\search_api_attachments\Plugin\search_api_attachments;
 
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Messenger\MessengerInterface;
-use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
+use Drupal\file\Entity\File;
 use Drupal\search_api_attachments\TextExtractorPluginBase;
-use GuzzleHttp\ClientInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\Mime\MimeTypeGuesserInterface;
-use Drupal\file\Entity\File;
 
 /**
  * Provides tika server extractor.
@@ -31,29 +25,13 @@ class TikaServerExtractor extends TextExtractorPluginBase {
    */
   protected $httpClient;
 
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactoryInterface $config_factory, StreamWrapperManagerInterface $stream_wrapper_manager, MimeTypeGuesserInterface $mime_type_guesser, MessengerInterface $messenger, FileSystemInterface $file_system, ClientInterface $http_client) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $config_factory, $stream_wrapper_manager, $mime_type_guesser, $messenger, $file_system);
-    $this->httpClient = $http_client;
-  }
-
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('config.factory'),
-      $container->get('stream_wrapper_manager'),
-      $container->get('file.mime_type.guesser'),
-      $container->get('messenger'),
-      $container->get('file_system'),
-      $container->get('http_client')
-    );
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->httpClient = $container->get('http_client');
+    return $instance;
   }
 
   /**
diff --git a/src/TextExtractorPluginBase.php b/src/TextExtractorPluginBase.php
index e7274d7eb0ed7e90dfdba24ab95279d1ccb91ffe..f2900a3d0ed816c9042339575b9e351c3ddbb90f 100644
--- a/src/TextExtractorPluginBase.php
+++ b/src/TextExtractorPluginBase.php
@@ -2,16 +2,12 @@
 
 namespace Drupal\search_api_attachments;
 
-use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\StreamWrapper\StreamWrapperInterface;
-use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
 use Drupal\file\Entity\File;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\Mime\MimeTypeGuesserInterface;
 
 /**
  * Base class for plugins able to extract file content.
@@ -42,7 +38,7 @@ abstract class TextExtractorPluginBase extends PluginBase implements TextExtract
   /**
    * Mime type guesser service.
    *
-   * @var \Symfony\Component\Mime\MimeTypeGuesserInterfacer
+   * @var \Symfony\Component\Mime\MimeTypeGuesserInterface
    */
   protected $mimeTypeGuesser;
 
@@ -56,21 +52,21 @@ abstract class TextExtractorPluginBase extends PluginBase implements TextExtract
   /**
    * {@inheritdoc}
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactoryInterface $config_factory, StreamWrapperManagerInterface $stream_wrapper_manager, MimeTypeGuesserInterface $mime_type_guesser, MessengerInterface $messenger) {
+  // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found
+  final public function __construct(array $configuration, $plugin_id, $plugin_definition) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->configFactory = $config_factory;
-    $this->streamWrapperManager = $stream_wrapper_manager;
-    $this->mimeTypeGuesser = $mime_type_guesser;
-    $this->messenger = $messenger;
   }
 
   /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-        $configuration, $plugin_id, $plugin_definition, $container->get('config.factory'), $container->get('stream_wrapper_manager'), $container->get('file.mime_type.guesser'), $container->get('messenger')
-    );
+    $instance = new static($configuration, $plugin_id, $plugin_definition);
+    $instance->configFactory = $container->get('config.factory');
+    $instance->streamWrapperManager = $container->get('stream_wrapper_manager');
+    $instance->mimeTypeGuesser = $container->get('file.mime_type.guesser');
+    $instance->messenger = $container->get('messenger');
+    return $instance;
   }
 
   /**
diff --git a/src/TextExtractorPluginInterface.php b/src/TextExtractorPluginInterface.php
index 4b82e56e5dad005a77bc3eba7bbb6b6ac9fe6c57..bb3c93ad8c93daad669d55105f59f490d03f619d 100644
--- a/src/TextExtractorPluginInterface.php
+++ b/src/TextExtractorPluginInterface.php
@@ -2,8 +2,8 @@
 
 namespace Drupal\search_api_attachments;
 
-use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Component\Plugin\ConfigurableInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\file\Entity\File;
 
 /**
diff --git a/tests/src/Unit/ExtractBody.php b/tests/src/Unit/ExtractBody.php
index 0e012ce5f0a49a560a40656a023f8af84f408b06..133f32f09241edb9882a20460ca205fd11d0a66f 100644
--- a/tests/src/Unit/ExtractBody.php
+++ b/tests/src/Unit/ExtractBody.php
@@ -2,8 +2,8 @@
 
 namespace Drupal\Tests\search_api_attachments\Unit;
 
-use Drupal\search_api_attachments\Plugin\search_api_attachments\SolrExtractor;
 use Drupal\Tests\UnitTestCase;
+use Drupal\search_api_attachments\Plugin\search_api_attachments\SolrExtractor;
 
 /**
  * Tests extracting body text from xml.
@@ -29,7 +29,8 @@ class ExtractBody extends UnitTestCase {
    *
    * @see testSetValue()
    */
-  public function xmlstringProvider() {
+  public static function xmlstringProvider() {
+    // phpcs:disable Drupal.Arrays.Array.LongLineDeclaration
     return [
       // Simple.
       ["<?xml?><html><head><title>ABC</title></head><body>No Tags</body></html>", "No Tags"],
@@ -114,6 +115,7 @@ Yay!</p>
 ',
       ],
     ];
+    // phpcs:enable Drupal.Arrays.Array.LongLineDeclaration
   }
 
 }