diff --git a/apps/files/lib/Controller/TemplateController.php b/apps/files/lib/Controller/TemplateController.php
index 5a1633432236550dcfaebb61e6b0be93930d97cc..b17d9336a948d0acdbc3fe43669b5ff3c4daf129 100644
--- a/apps/files/lib/Controller/TemplateController.php
+++ b/apps/files/lib/Controller/TemplateController.php
@@ -44,7 +44,7 @@ class TemplateController extends OCSController {
 	 * @NoAdminRequired
 	 */
 	public function list(): DataResponse {
-		return new DataResponse($this->templateManager->listCreators());
+		return new DataResponse($this->templateManager->listTemplates());
 	}
 
 	/**
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 63cd4db59595826815e8ba862a5dde37a9557cb0..f51274171f0aa2a05f806a413f6ed288629a67f0 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -315,7 +315,7 @@ return array(
     'OCP\\Files\\Storage\\IStorage' => $baseDir . '/lib/public/Files/Storage/IStorage.php',
     'OCP\\Files\\Storage\\IStorageFactory' => $baseDir . '/lib/public/Files/Storage/IStorageFactory.php',
     'OCP\\Files\\Storage\\IWriteStreamStorage' => $baseDir . '/lib/public/Files/Storage/IWriteStreamStorage.php',
-    'OCP\\Files\\Template\\CreatedFromTemplateEvent' => $baseDir . '/lib/public/Files/Template/CreatedFromTemplateEvent.php',
+    'OCP\\Files\\Template\\FileCreatedFromTemplateEvent' => $baseDir . '/lib/public/Files/Template/FileCreatedFromTemplateEvent.php',
     'OCP\\Files\\Template\\ICustomTemplateProvider' => $baseDir . '/lib/public/Files/Template/ICustomTemplateProvider.php',
     'OCP\\Files\\Template\\ITemplateManager' => $baseDir . '/lib/public/Files/Template/ITemplateManager.php',
     'OCP\\Files\\Template\\Template' => $baseDir . '/lib/public/Files/Template/Template.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 6bcd72d01f0ad5a7fce1d224041e97fff41f43b9..3f1983a11c0ed79ac1f58f3f74ce5a32b7e24a9a 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -344,7 +344,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
         'OCP\\Files\\Storage\\IStorage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IStorage.php',
         'OCP\\Files\\Storage\\IStorageFactory' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IStorageFactory.php',
         'OCP\\Files\\Storage\\IWriteStreamStorage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IWriteStreamStorage.php',
-        'OCP\\Files\\Template\\CreatedFromTemplateEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Template/CreatedFromTemplateEvent.php',
+        'OCP\\Files\\Template\\FileCreatedFromTemplateEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Template/FileCreatedFromTemplateEvent.php',
         'OCP\\Files\\Template\\ICustomTemplateProvider' => __DIR__ . '/../../..' . '/lib/public/Files/Template/ICustomTemplateProvider.php',
         'OCP\\Files\\Template\\ITemplateManager' => __DIR__ . '/../../..' . '/lib/public/Files/Template/ITemplateManager.php',
         'OCP\\Files\\Template\\Template' => __DIR__ . '/../../..' . '/lib/public/Files/Template/Template.php',
diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
index d6271f5ce45b51809af77b54fa0da667c8c091ef..d2dc365d8350b8b3ac7cb5a9171f0ed07a65837f 100644
--- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php
+++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
@@ -77,6 +77,9 @@ class RegistrationContext {
 	/** @var array[] */
 	private $wellKnownHandlers = [];
 
+	/** @var array[] */
+	private $templateProviders = [];
+
 	/** @var ILogger */
 	private $logger;
 
@@ -186,6 +189,13 @@ class RegistrationContext {
 					$class
 				);
 			}
+
+			public function registerTemplateProvider(string $providerClass): void {
+				$this->context->registerTemplateProvider(
+					$this->appId,
+					$providerClass
+				);
+			}
 		};
 	}
 
@@ -279,6 +289,13 @@ class RegistrationContext {
 		];
 	}
 
+	public function registerTemplateProvider(string $appId, string $class): void {
+		$this->templateProviders[] = [
+			'appId' => $appId,
+			'class' => $class,
+		];
+	}
+
 	/**
 	 * @param App[] $apps
 	 */
@@ -451,7 +468,7 @@ class RegistrationContext {
 	}
 
 	/**
-	 * @erturn array[]
+	 * @return array[]
 	 */
 	public function getInitialStates(): array {
 		return $this->initialStates;
@@ -463,4 +480,8 @@ class RegistrationContext {
 	public function getWellKnownHandlers(): array {
 		return $this->wellKnownHandlers;
 	}
+
+	public function getTemplateProviders(): array {
+		return $this->templateProviders;
+	}
 }
diff --git a/lib/private/Files/Template/TemplateManager.php b/lib/private/Files/Template/TemplateManager.php
index 1942f83b86cef349a00830bc05d372f5f68a9633..813f3fe83e94cea21ec2a1ee3dd31d9756cf978b 100644
--- a/lib/private/Files/Template/TemplateManager.php
+++ b/lib/private/Files/Template/TemplateManager.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
 
 namespace OC\Files\Template;
 
+use OC\AppFramework\Bootstrap\Coordinator;
 use OC\Files\Cache\Scanner;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\Files\Folder;
@@ -35,7 +36,7 @@ use OCP\Files\IRootFolder;
 use OCP\Files\Node;
 use OCP\Files\NotFoundException;
 use OCP\Files\NotPermittedException;
-use OCP\Files\Template\CreatedFromTemplateEvent;
+use OCP\Files\Template\FileCreatedFromTemplateEvent;
 use OCP\Files\Template\ICustomTemplateProvider;
 use OCP\Files\Template\ITemplateManager;
 use OCP\Files\Template\Template;
@@ -48,10 +49,11 @@ use OCP\L10N\IFactory;
 use Psr\Log\LoggerInterface;
 
 class TemplateManager implements ITemplateManager {
+	private $registeredTypes = [];
 	private $types = [];
 
-	private $registeredProviders = [];
-	private $providers;
+	/** @var array|null */
+	private $providers = null;
 
 	private $serverContainer;
 	private $eventDispatcher;
@@ -62,10 +64,13 @@ class TemplateManager implements ITemplateManager {
 	private $logger;
 	private $userId;
 	private $l10nFactory;
+	/** @var Coordinator */
+	private $bootstrapCoordinator;
 
 	public function __construct(
 		IServerContainer $serverContainer,
 		IEventDispatcher $eventDispatcher,
+		Coordinator $coordinator,
 		IRootFolder $rootFolder,
 		IUserSession $userSession,
 		IPreview $previewManager,
@@ -75,6 +80,7 @@ class TemplateManager implements ITemplateManager {
 	) {
 		$this->serverContainer = $serverContainer;
 		$this->eventDispatcher = $eventDispatcher;
+		$this->bootstrapCoordinator = $coordinator;
 		$this->rootFolder = $rootFolder;
 		$this->previewManager = $previewManager;
 		$this->config = $config;
@@ -85,39 +91,45 @@ class TemplateManager implements ITemplateManager {
 		$this->userId = $user ? $user->getUID() : null;
 	}
 
-	public function registerTemplateFileCreator(TemplateFileCreator $templateType): void {
-		$this->types[] = $templateType;
-	}
-
-	public function registerTemplateProvider(string $providerClass): void {
-		$this->registeredProviders[] = $providerClass;
+	public function registerTemplateFileCreator(callable $callback): void {
+		$this->registeredTypes[] = $callback;
 	}
 
 	public function getRegisteredProviders(): array {
 		if ($this->providers !== null) {
 			return $this->providers;
 		}
+
+		$context = $this->bootstrapCoordinator->getRegistrationContext();
+
 		$this->providers = [];
-		foreach ($this->registeredProviders as $providerClass) {
-			$this->providers[$providerClass] = $this->serverContainer->get($providerClass);
+		foreach ($context->getTemplateProviders() as $provider) {
+			$this->providers[$provider['class']] = $this->serverContainer->get($provider['class']);
 		}
 		return $this->providers;
 	}
 
-	public function listCreators():? array {
-		if ($this->types === null) {
-			return null;
+	public function getTypes(): array {
+		foreach ($this->registeredTypes as $registeredType) {
+			$this->types[] = $registeredType();
 		}
+		return $this->types;
+	}
 
-		usort($this->types, function (TemplateFileCreator $a, TemplateFileCreator $b) {
+	public function listCreators(): array {
+		$types = $this->getTypes();
+		usort($types, function (TemplateFileCreator $a, TemplateFileCreator $b) {
 			return $a->getOrder() - $b->getOrder();
 		});
+		return $types;
+	}
 
+	public function listTemplates(): array {
 		return array_map(function (TemplateFileCreator $entry) {
 			return array_merge($entry->jsonSerialize(), [
 				'templates' => $this->getTemplateFiles($entry)
 			]);
-		}, $this->types);
+		}, $this->listCreators());
 	}
 
 	/**
@@ -148,7 +160,7 @@ class TemplateManager implements ITemplateManager {
 					$template->copy($targetFile->getPath());
 				}
 			}
-			$this->eventDispatcher->dispatchTyped(new CreatedFromTemplateEvent($template, $targetFile));
+			$this->eventDispatcher->dispatchTyped(new FileCreatedFromTemplateEvent($template, $targetFile));
 			return $this->formatFile($userFolder->get($filePath));
 		} catch (\Exception $e) {
 			$this->logger->error($e->getMessage(), ['exception' => $e]);
diff --git a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
index 197275fb8e332c2f98723c425a2cd1cea48f1ea9..8bc21a545f6d0dc1cd400557a15679a93e5f7f44 100644
--- a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
+++ b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
@@ -31,6 +31,7 @@ namespace OCP\AppFramework\Bootstrap;
 
 use OCP\AppFramework\IAppContainer;
 use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Template\ICustomTemplateProvider;
 use OCP\IContainer;
 
 /**
@@ -196,4 +197,14 @@ interface IRegistrationContext {
 	 * @since 21.0.0
 	 */
 	public function registerWellKnownHandler(string $class): void;
+
+	/**
+	 * Register a custom template provider class that is able to inject custom templates
+	 * in addition to the user defined ones
+	 *
+	 * @param string $providerClass
+	 * @psalm-param class-string<ICustomTemplateProvider> $providerClass
+	 * @since 21.0.0
+	 */
+	public function registerTemplateProvider(string $providerClass): void;
 }
diff --git a/lib/public/Files/Template/CreatedFromTemplateEvent.php b/lib/public/Files/Template/FileCreatedFromTemplateEvent.php
similarity index 96%
rename from lib/public/Files/Template/CreatedFromTemplateEvent.php
rename to lib/public/Files/Template/FileCreatedFromTemplateEvent.php
index 8d8028144068431e963849e5f4883a24873b532a..7ed342e400768007937130a662eb017c5c8c0a83 100644
--- a/lib/public/Files/Template/CreatedFromTemplateEvent.php
+++ b/lib/public/Files/Template/FileCreatedFromTemplateEvent.php
@@ -32,7 +32,7 @@ use OCP\Files\File;
 /**
  * @since 21.0.0
  */
-class CreatedFromTemplateEvent extends Event {
+class FileCreatedFromTemplateEvent extends Event {
 	private $template;
 	private $target;
 
diff --git a/lib/public/Files/Template/ITemplateManager.php b/lib/public/Files/Template/ITemplateManager.php
index 58b5b6c48461be05436dd2141a148ab7b470ce66..39a48598508a991f81b4a4c4c6863cc06134e2a9 100644
--- a/lib/public/Files/Template/ITemplateManager.php
+++ b/lib/public/Files/Template/ITemplateManager.php
@@ -36,19 +36,18 @@ interface ITemplateManager {
 	/**
 	 * Register a template type support
 	 *
-	 * @param TemplateFileCreator $templateType
+	 * @param callable(): TemplateFileCreator $callback A callback which returns the TemplateFileCreator instance to register
 	 * @since 21.0.0
 	 */
-	public function registerTemplateFileCreator(TemplateFileCreator $templateType): void;
+	public function registerTemplateFileCreator(callable $callback): void;
 
 	/**
-	 * Register a custom template provider class that is able to inject custom templates
-	 * in addition to the user defined ones
+	 * Get a list of available file creators
 	 *
-	 * @param string $providerClass
+	 * @return array
 	 * @since 21.0.0
 	 */
-	public function registerTemplateProvider(string $providerClass): void;
+	public function listCreators(): array;
 
 	/**
 	 * Get a list of available file creators and their offered templates
@@ -56,7 +55,7 @@ interface ITemplateManager {
 	 * @return array
 	 * @since 21.0.0
 	 */
-	public function listCreators():? array;
+	public function listTemplates(): array;
 
 	/**
 	 * @return bool