diff --git a/core/modules/migrate/migrate.services.yml b/core/modules/migrate/migrate.services.yml
index 3f2d32d..a2f0dd6 100644
--- a/core/modules/migrate/migrate.services.yml
+++ b/core/modules/migrate/migrate.services.yml
@@ -17,6 +17,9 @@ services:
   plugin.manager.migrate.id_map:
     class: Drupal\migrate\Plugin\MigratePluginManager
     arguments: [id_map, '@container.namespaces', '@cache.discovery', '@module_handler']
+  plugin.manager.migrate.generator:
+    class: Drupal\migrate\Plugin\MigratePluginManager
+    arguments: [generator, '@container.namespaces', '@cache.discovery', '@module_handler']
   password_migrate:
     class: Drupal\migrate\MigratePassword
     arguments: ['@password_original']
diff --git a/core/modules/migrate/src/Plugin/MigrateGeneratorInterface.php b/core/modules/migrate/src/Plugin/MigrateGeneratorInterface.php
new file mode 100644
index 0000000..818ce59
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/MigrateGeneratorInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate\Plugin\MigrateGeneratorInterface.
+ */
+
+namespace Drupal\migrate\Plugin;
+
+/**
+ * Defines the generator plugin type, which can dynamically build migration
+ * entities from templates.
+ */
+interface MigrateGeneratorInterface {
+
+  /**
+   * Generates migration(s) from a template.
+   *
+   * @param array $template
+   *  The migration template. This can be a complete or partial migration, as
+   *  parsed from a YAML file.
+   * @param \Drupal\migrate\Plugin\MigrateSourceInterface|NULL $source
+   *  The fully initialized source plugin, or NULL if the source is
+   *  indeterminate (i.e., intended to be set by the generator).
+   *
+   * @return \Drupal\migrate\Entity\MigrationInterface[]
+   *  The unsaved, generated migration entities.
+   */
+  public function generate(array $template, MigrateSourceInterface $source = NULL);
+
+}
