diff --git a/islandora.services.yml b/islandora.services.yml
index 4b3a9d16..e48818b9 100644
--- a/islandora.services.yml
+++ b/islandora.services.yml
@@ -59,3 +59,9 @@ services:
     arguments: ['@jwt.authentication.jwt']
     tags:
       - { name: event_subscriber }
+  islandora.upload_children.batch_processor:
+    class: Drupal\islandora\Form\AddChildrenWizard\BatchProcessor
+    arguments:
+      - '@entity_type.manager'
+      - '@database'
+      - '@current_user'
diff --git a/src/Form/AddChildrenWizard/BatchProcessor.php b/src/Form/AddChildrenWizard/BatchProcessor.php
new file mode 100644
index 00000000..2e4a84bf
--- /dev/null
+++ b/src/Form/AddChildrenWizard/BatchProcessor.php
@@ -0,0 +1,190 @@
+<?php
+
+namespace Drupal\islandora\Form\AddChildrenWizard;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Session\AccountProxyInterface;
+use Drupal\Core\Url;
+use Drupal\islandora\IslandoraUtils;
+use Drupal\node\NodeInterface;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+
+/**
+ * Children addition batch processor.
+ */
+class BatchProcessor {
+
+  use FieldTrait;
+
+  /**
+   * The entity type manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|null
+   */
+  protected ?EntityTypeManagerInterface $entityTypeManager;
+
+  /**
+   * The database connection serivce.
+   *
+   * @var \Drupal\Core\Database\Connection|null
+   */
+  protected ?Connection $database;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountProxyInterface|null
+   */
+  protected ?AccountProxyInterface $currentUser;
+
+  /**
+   * Constructor.
+   */
+  public function __construct(
+    EntityTypeManagerInterface $entity_type_manager,
+    Connection $database,
+    AccountProxyInterface $current_user
+  ) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->database = $database;
+    $this->currentUser = $current_user;
+  }
+
+  /**
+   * Implements callback_batch_operation() for our child addition batch.
+   */
+  public function batchOperation($delta, $info, array $values, &$context) {
+    $transaction = $this->database->startTransaction();
+
+    try {
+      $taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
+
+      /** @var \Drupal\file\FileInterface $file */
+      $file = $this->entityTypeManager->getStorage('file')->load($info['target_id']);
+      $file->setPermanent();
+      if ($file->save() !== SAVED_UPDATED) {
+        throw new \Exception("Failed to update file '{$file->id()}' to be permanent.");
+      }
+
+      $node_storage = $this->entityTypeManager->getStorage('node');
+      $parent = $node_storage->load($values['node']);
+
+      // Create a node (with the filename?) (and also belonging to the target
+      // node).
+      /** @var \Drupal\node\NodeInterface $node */
+      $node = $node_storage->create([
+        'type' => $values['bundle'],
+        'title' => $file->getFilename(),
+        IslandoraUtils::MEMBER_OF_FIELD => $parent,
+        'uid' => $this->currentUser->id(),
+        'status' => NodeInterface::PUBLISHED,
+        IslandoraUtils::MODEL_FIELD => ($values['model'] ?
+          $taxonomy_term_storage->load($values['model']) :
+          NULL),
+      ]);
+
+      if ($node->save() !== SAVED_NEW) {
+        throw new \Exception("Failed to create node for file '{$file->id()}'.");
+      }
+
+      // Create a media with the file attached and also pointing at the node.
+      $field = $this->getField($values);
+
+      $media_values = array_merge(
+        [
+          'bundle' => $values['media_type'],
+          'name' => $file->getFilename(),
+          IslandoraUtils::MEDIA_OF_FIELD => $node,
+          IslandoraUtils::MEDIA_USAGE_FIELD => ($values['use'] ?
+            $taxonomy_term_storage->loadMultiple($values['use']) :
+            NULL),
+          'uid' => $this->currentUser->id(),
+          // XXX: Published... no constant?
+          'status' => 1,
+        ],
+        [
+          $field->getName() => [
+            $info,
+          ],
+        ]
+      );
+      $media = $this->entityTypeManager->getStorage('media')->create($media_values);
+      if ($media->save() !== SAVED_NEW) {
+        throw new \Exception("Failed to create media for file '{$file->id()}.");
+      }
+
+      $context['results'] = array_merge_recursive($context['results'], [
+        'validation_violations' => $this->validationClassification([
+          $file,
+          $media,
+          $node,
+        ]),
+      ]);
+      $context['results']['count'] += 1;
+    }
+    catch (HttpExceptionInterface $e) {
+      $transaction->rollBack();
+      throw $e;
+    }
+    catch (\Exception $e) {
+      $transaction->rollBack();
+      throw new HttpException(500, $e->getMessage(), $e);
+    }
+  }
+
+  /**
+   * Helper to bulk process validatable entities.
+   *
+   * @param array $entities
+   *   An array of entities to scan for validation violations.
+   *
+   * @return array
+   *   An associative array mapping entity type IDs to entity IDs to a count
+   *   of validation violations found on then given entity.
+   */
+  protected function validationClassification(array $entities) {
+    $violations = [];
+
+    foreach ($entities as $entity) {
+      $entity_violations = $entity->validate();
+      if ($entity_violations->count() > 0) {
+        $violations[$entity->getEntityTypeId()][$entity->id()] = $entity_violations->count();
+      }
+    }
+
+    return $violations;
+  }
+
+  /**
+   * Implements callback_batch_finished() for our child addition batch.
+   */
+  public function batchProcessFinished($success, $results, $operations): void {
+    if ($success) {
+      $this->messenger()->addMessage($this->formatPlural(
+        $results['count'],
+        'Added 1 child node.',
+        'Added @count child nodes.'
+      ));
+      foreach ($results['validation_violations'] ?? [] as $entity_type => $info) {
+        foreach ($info as $id => $count) {
+          $this->messenger()->addWarning($this->formatPlural(
+            $count,
+            '1 validation error present in <a href=":uri">bulk created entity of type %type, with ID %id</a>.',
+            '@count validation errors present in <a href=":uri">bulk created entity of type %type, with ID %id</a>.',
+            [
+              '%type' => $entity_type,
+              ':uri' => Url::fromRoute("entity.{$entity_type}.canonical", [$entity_type => $id])->toString(),
+              '%id' => $id,
+            ]
+          ));
+        }
+      }
+    }
+    else {
+      $this->messenger()->addError($this->t('Encountered an error when adding children.'));
+    }
+  }
+
+}
diff --git a/src/Form/AddChildrenWizard/FieldTrait.php b/src/Form/AddChildrenWizard/FieldTrait.php
new file mode 100644
index 00000000..156000e3
--- /dev/null
+++ b/src/Form/AddChildrenWizard/FieldTrait.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Drupal\islandora\Form\AddChildrenWizard;
+
+use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+
+/**
+ * Field lookup helper trait.
+ */
+trait FieldTrait {
+
+  use MediaTypeTrait;
+
+  /**
+   * The entity field manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface|null
+   */
+  protected ?EntityFieldManagerInterface $entityFieldManager;
+
+  /**
+   * Helper; get field instance, given our required values.
+   *
+   * @param array $values
+   *   See ::getMediaType() for which values are required.
+   *
+   * @return \Drupal\Core\Field\FieldDefinitionInterface
+   *   The target field.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   */
+  protected function getField(array $values): FieldDefinitionInterface {
+    $media_type = $this->getMediaType($values);
+    $media_source = $media_type->getSource();
+    $source_field = $media_source->getSourceFieldDefinition($media_type);
+
+    $fields = $this->entityFieldManager()->getFieldDefinitions('media', $media_type->id());
+
+    return $fields[$source_field->getFieldStorageDefinition()->getName()] ??
+      $media_source->createSourceField();
+  }
+
+  /**
+   * Lazy-initialization of the entity field manager service.
+   *
+   * @return \Drupal\Core\Entity\EntityFieldManagerInterface
+   *   The entity field manager service.
+   */
+  protected function entityFieldManager() : EntityFieldManagerInterface {
+    if ($this->entityFieldManager === NULL) {
+      $this->setEntityFieldManager(\Drupal::service('entity_field.manager'));
+    }
+    return $this->entityFieldManager;
+  }
+
+  /**
+   * Setter for entity field manager.
+   */
+  public function setEntityFieldManager(EntityFieldManagerInterface $entity_field_manager) : self {
+    $this->entityFieldManager = $entity_field_manager;
+    return $this;
+  }
+
+}
diff --git a/src/Form/AddChildrenWizard/FileSelectionForm.php b/src/Form/AddChildrenWizard/FileSelectionForm.php
index 8d29bab3..084eb5e5 100644
--- a/src/Form/AddChildrenWizard/FileSelectionForm.php
+++ b/src/Form/AddChildrenWizard/FileSelectionForm.php
@@ -2,11 +2,8 @@
 
 namespace Drupal\islandora\Form\AddChildrenWizard;
 
-use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Core\Batch\BatchBuilder;
 use Drupal\Core\Database\Connection;
-use Drupal\Core\Entity\EntityFieldManagerInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemList;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
@@ -15,38 +12,19 @@ use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountProxyInterface;
 use Drupal\Core\Url;
-use Drupal\islandora\IslandoraUtils;
 use Drupal\media\MediaTypeInterface;
-use Drupal\node\NodeInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpKernel\Exception\HttpException;
-use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
 
 /**
  * Children addition wizard's second step.
  */
 class FileSelectionForm extends FormBase {
 
-  /**
-   * The entity type manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|null
-   */
-  protected ?EntityTypeManagerInterface $entityTypeManager;
-
-  /**
-   * The widget plugin manager service.
-   *
-   * @var \Drupal\Core\Field\WidgetPluginManager|null
-   */
-  protected ?PluginManagerInterface $widgetPluginManager;
-
-  /**
-   * The entity field manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityFieldManagerInterface|null
-   */
-  protected ?EntityFieldManagerInterface $entityFieldManager;
+  use WizardTrait {
+    WizardTrait::getField as doGetField;
+    WizardTrait::getMediaType as doGetMediaType;
+    WizardTrait::getWidget as doGetWidget;
+  }
 
   /**
    * The database connection serivce.
@@ -62,6 +40,13 @@ class FileSelectionForm extends FormBase {
    */
   protected ?AccountProxyInterface $currentUser;
 
+  /**
+   * The batch processor service.
+   *
+   * @var \Drupal\islandora\Form\AddChildrenWizard\BatchProcessor|null
+   */
+  protected ?BatchProcessor $batchProcessor;
+
   /**
    * {@inheritdoc}
    */
@@ -74,6 +59,8 @@ class FileSelectionForm extends FormBase {
     $instance->database = $container->get('database');
     $instance->currentUser = $container->get('current_user');
 
+    $instance->batchProcessor = $container->get('islandora.upload_children.batch_processor');
+
     return $instance;
   }
 
@@ -100,24 +87,6 @@ class FileSelectionForm extends FormBase {
     return $this->doGetMediaType($form_state->getTemporaryValue('wizard'));
   }
 
-  /**
-   * Helper; get media type, given our required values.
-   *
-   * @param array $values
-   *   An associative array which must contain at least:
-   *   - media_type: The machine name of the media type to load.
-   *
-   * @return \Drupal\media\MediaTypeInterface
-   *   The loaded media type.
-   *
-   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
-   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
-   */
-  protected function doGetMediaType(array $values): MediaTypeInterface {
-    /** @var \Drupal\media\MediaTypeInterface $media_type */
-    return $this->entityTypeManager->getStorage('media_type')->load($values['media_type']);
-  }
-
   /**
    * Helper; get field instance, based off discovering from form state.
    *
@@ -136,26 +105,6 @@ class FileSelectionForm extends FormBase {
     return $field;
   }
 
-  /**
-   * Helper; get field instance, given our required values.
-   *
-   * @param array $values
-   *   See ::doGetMediaType() for which values are required.
-   *
-   * @return \Drupal\Core\Field\FieldDefinitionInterface
-   *   The target field.
-   */
-  protected function doGetField(array $values): FieldDefinitionInterface {
-    $media_type = $this->doGetMediaType($values);
-    $media_source = $media_type->getSource();
-    $source_field = $media_source->getSourceFieldDefinition($media_type);
-
-    $fields = $this->entityFieldManager->getFieldDefinitions('media', $media_type->id());
-
-    return $fields[$source_field->getFieldStorageDefinition()->getName()] ??
-      $media_source->createSourceField();
-  }
-
   /**
    * Helper; get widget for the field, based on discovering from form state.
    *
@@ -169,23 +118,6 @@ class FileSelectionForm extends FormBase {
     return $this->doGetWidget($this->getField($form_state));
   }
 
-  /**
-   * Helper; get the base widget for the given field.
-   *
-   * @param \Drupal\Core\Field\FieldDefinitionInterface $field
-   *   The field for which get obtain the widget.
-   *
-   * @return \Drupal\Core\Field\WidgetInterface
-   *   The widget.
-   */
-  protected function doGetWidget(FieldDefinitionInterface $field): WidgetInterface {
-    return $this->widgetPluginManager->getInstance([
-      'field_definition' => $field,
-      'form_mode' => 'default',
-      'prepare' => TRUE,
-    ]);
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -218,12 +150,12 @@ class FileSelectionForm extends FormBase {
     $builder = (new BatchBuilder())
       ->setTitle($this->t('Creating children...'))
       ->setInitMessage($this->t('Initializing...'))
-      ->setFinishCallback([$this, 'batchProcessFinished']);
+      ->setFinishCallback([$this->batchProcessor, 'batchProcessFinished']);
     $values = $form_state->getValue($this->doGetField($cached_values)->getName());
     $massaged_values = $widget->massageFormValues($values, $form, $form_state);
     foreach ($massaged_values as $delta => $file) {
       $builder->addOperation(
-        [$this, 'batchProcess'],
+        [$this->batchProcessor, 'batchOperation'],
         [$delta, $file, $cached_values]
       );
     }
@@ -231,134 +163,4 @@ class FileSelectionForm extends FormBase {
     $form_state->setRedirectUrl(Url::fromUri("internal:/node/{$cached_values['node']}/members"));
   }
 
-  /**
-   * Implements callback_batch_operation() for our child addition batch.
-   */
-  public function batchProcess($delta, $info, array $values, &$context) {
-    $transaction = $this->database->startTransaction();
-
-    try {
-      $taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
-
-      /** @var \Drupal\file\FileInterface $file */
-      $file = $this->entityTypeManager->getStorage('file')->load($info['target_id']);
-      $file->setPermanent();
-      if ($file->save() !== SAVED_UPDATED) {
-        throw new \Exception("Failed to update file '{$file->id()}' to be permanent.");
-      }
-
-      $node_storage = $this->entityTypeManager->getStorage('node');
-      $parent = $node_storage->load($values['node']);
-
-      // Create a node (with the filename?) (and also belonging to the target
-      // node).
-      /** @var \Drupal\node\NodeInterface $node */
-      $node = $node_storage->create([
-        'type' => $values['bundle'],
-        'title' => $file->getFilename(),
-        IslandoraUtils::MEMBER_OF_FIELD => $parent,
-        'uid' => $this->currentUser->id(),
-        'status' => NodeInterface::PUBLISHED,
-        IslandoraUtils::MODEL_FIELD => ($values['model'] ?
-          $taxonomy_term_storage->load($values['model']) :
-          NULL),
-      ]);
-
-      if ($node->save() !== SAVED_NEW) {
-        throw new \Exception("Failed to create node for file '{$file->id()}'.");
-      }
-
-      // Create a media with the file attached and also pointing at the node.
-      $field = $this->doGetField($values);
-
-      $media_values = array_merge(
-        [
-          'bundle' => $values['media_type'],
-          'name' => $file->getFilename(),
-          IslandoraUtils::MEDIA_OF_FIELD => $node,
-          IslandoraUtils::MEDIA_USAGE_FIELD => ($values['use'] ?
-            $taxonomy_term_storage->loadMultiple($values['use']) :
-            NULL),
-          'uid' => $this->currentUser->id(),
-          // XXX: Published... no constant?
-          'status' => 1,
-        ],
-        [
-          $field->getName() => [
-            $info,
-          ],
-        ]
-      );
-      $media = $this->entityTypeManager->getStorage('media')->create($media_values);
-      if ($media->save() !== SAVED_NEW) {
-        throw new \Exception("Failed to create media for file '{$file->id()}.");
-      }
-
-      $context['results'] = array_merge_recursive($context['results'], [
-        'validation_violations' => $this->validationClassification([
-          $file,
-          $media,
-          $node,
-        ]),
-      ]);
-      $context['results']['count'] += 1;
-    }
-    catch (HttpExceptionInterface $e) {
-      $transaction->rollBack();
-      throw $e;
-    }
-    catch (\Exception $e) {
-      $transaction->rollBack();
-      throw new HttpException(500, $e->getMessage(), $e);
-    }
-  }
-
-  /**
-   * @param array $entities
-   *
-   * @return array
-   */
-  protected function validationClassification(array $entities) {
-    $violations = [];
-
-    foreach ($entities as $entity) {
-      $entity_violations = $entity->validate();
-      if ($entity_violations->count() > 0) {
-        $violations[$entity->getEntityTypeId()][$entity->id()] = $entity_violations->count();
-      }
-    }
-
-    return $violations;
-  }
-
-  /**
-   * Implements callback_batch_finished() for our child addition batch.
-   */
-  public function batchProcessFinished($success, $results, $operations): void {
-    if ($success) {
-      $this->messenger()->addMessage($this->formatPlural(
-        $results['count'],
-        'Added 1 child node.',
-        'Added @count child nodes.'
-      ));
-      foreach ($results['validation_violations'] ?? [] as $entity_type => $info) {
-        foreach ($info as $id => $count) {
-          $this->messenger()->addWarning($this->formatPlural(
-            $count,
-            '1 validation error present in <a href=":uri">bulk created entity of type %type, with ID %id</a>.',
-            '@count validation errors present in <a href=":uri">bulk created entity of type %type, with ID %id</a>.',
-            [
-              '%type' => $entity_type,
-              ':uri' => Url::fromRoute("entity.{$entity_type}.canonical", [$entity_type => $id])->toString(),
-              '%id' => $id,
-            ]
-          ));
-        }
-      }
-    }
-    else {
-      $this->messenger()->addError($this->t('Encountered an error when adding children.'));
-    }
-  }
-
 }
diff --git a/src/Form/AddChildrenWizard/Form.php b/src/Form/AddChildrenWizard/Form.php
index 68489f18..97ac8b23 100644
--- a/src/Form/AddChildrenWizard/Form.php
+++ b/src/Form/AddChildrenWizard/Form.php
@@ -2,10 +2,8 @@
 
 namespace Drupal\islandora\Form\AddChildrenWizard;
 
-use Drupal\Core\Access\AccessResult;
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
 use Drupal\Core\Form\FormBuilderInterface;
-use Drupal\Core\Routing\RouteMatch;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Session\AccountProxyInterface;
 use Drupal\Core\TempStore\SharedTempStoreFactory;
@@ -56,8 +54,6 @@ class Form extends FormWizardBase {
     EventDispatcherInterface $event_dispatcher,
     RouteMatchInterface $route_match,
     $tempstore_id,
-    IslandoraUtils $utils,
-    RouteMatchInterface $current_route_match,
     AccountProxyInterface $current_user,
     $machine_name = NULL,
     $step = NULL
@@ -65,9 +61,7 @@ class Form extends FormWizardBase {
     parent::__construct($tempstore, $builder, $class_resolver, $event_dispatcher, $route_match, $tempstore_id,
       $machine_name, $step);
 
-    $this->utils = $utils;
-    $this->currentRoute = $current_route_match;
-    $this->nodeId = $this->currentRoute->getParameter('node');
+    $this->nodeId = $this->routeMatch->getParameter('node');
     $this->currentUser = $current_user;
   }
 
@@ -78,10 +72,9 @@ class Form extends FormWizardBase {
     return array_merge(
       parent::getParameters(),
       [
-        'utils' => \Drupal::service('islandora.utils'),
         'tempstore_id' => 'islandora.upload_children',
-        'current_route_match' => \Drupal::service('current_route_match'),
         'current_user' => \Drupal::service('current_user'),
+        'batch_processor' => \Drupal::service('islandora.upload_children.batch_processor'),
       ]
     );
   }
diff --git a/src/Form/AddChildrenWizard/MediaTypeTrait.php b/src/Form/AddChildrenWizard/MediaTypeTrait.php
new file mode 100644
index 00000000..e2caf2c2
--- /dev/null
+++ b/src/Form/AddChildrenWizard/MediaTypeTrait.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\islandora\Form\AddChildrenWizard;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\media\MediaTypeInterface;
+
+/**
+ * Media type lookup helper trait.
+ */
+trait MediaTypeTrait {
+
+  /**
+   * The entity type manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface|null
+   */
+  protected ?EntityTypeManagerInterface $entityTypeManager;
+
+  /**
+   * Helper; get media type, given our required values.
+   *
+   * @param array $values
+   *   An associative array which must contain at least:
+   *   - media_type: The machine name of the media type to load.
+   *
+   * @return \Drupal\media\MediaTypeInterface
+   *   The loaded media type.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   */
+  protected function getMediaType(array $values): MediaTypeInterface {
+    /** @var \Drupal\media\MediaTypeInterface $media_type */
+    return $this->entityTypeManager()->getStorage('media_type')->load($values['media_type']);
+  }
+
+  /**
+   * Lazy-initialization of the entity type manager service.
+   *
+   * @return \Drupal\Core\Entity\EntityTypeManagerInterface
+   *   The entity type manager service.
+   */
+  protected function entityTypeManager() : EntityTypeManagerInterface {
+    if ($this->entityTypeManager === NULL) {
+      $this->setEntityTypeManager(\Drupal::service('entity_type.manager'));
+    }
+    return $this->entityTypeManager;
+  }
+
+  /**
+   * Setter for the entity type manager service.
+   */
+  public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) : self {
+    $this->entityTypeManager = $entity_type_manager;
+    return $this;
+  }
+
+}
diff --git a/src/Form/AddChildrenWizard/WizardTrait.php b/src/Form/AddChildrenWizard/WizardTrait.php
new file mode 100644
index 00000000..dd56450f
--- /dev/null
+++ b/src/Form/AddChildrenWizard/WizardTrait.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\islandora\Form\AddChildrenWizard;
+
+use Drupal\Component\Plugin\PluginManagerInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\WidgetInterface;
+
+/**
+ * Wizard/widget lookup helper trait.
+ */
+trait WizardTrait {
+
+  use FieldTrait;
+
+  /**
+   * The widget plugin manager service.
+   *
+   * @var \Drupal\Core\Field\WidgetPluginManager
+   */
+  protected PluginManagerInterface $widgetPluginManager;
+
+  /**
+   * Helper; get the base widget for the given field.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field
+   *   The field for which get obtain the widget.
+   *
+   * @return \Drupal\Core\Field\WidgetInterface
+   *   The widget.
+   */
+  protected function getWidget(FieldDefinitionInterface $field): WidgetInterface {
+    return $this->widgetPluginManager->getInstance([
+      'field_definition' => $field,
+      'form_mode' => 'default',
+      'prepare' => TRUE,
+    ]);
+  }
+
+}