diff --git a/apps/files/lib/AppInfo/Application.php b/apps/files/lib/AppInfo/Application.php index 025e6c42f2805..9fcad2e972878 100644 --- a/apps/files/lib/AppInfo/Application.php +++ b/apps/files/lib/AppInfo/Application.php @@ -64,6 +64,7 @@ use OCP\Share\IManager as IShareManager; use OCP\Util; use Psr\Container\ContainerInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; class Application extends App implements IBootstrap { public const APP_ID = 'files'; @@ -121,12 +122,16 @@ public function register(IRegistrationContext $context): void { $context->registerNotifierService(Notifier::class); } - public function boot(IBootContext $context): void { - $context->injectFn(Closure::fromCallable([$this, 'registerCollaboration'])); - $context->injectFn([Listener::class, 'register']); - $context->injectFn(Closure::fromCallable([$this, 'registerSearchProvider'])); + public function boot(IBootContext $context, + IProviderManager $providerManager, + EventDispatcherInterface $dispatcher, + ISearch $search, + IL10N $l10n): void { + $this->registerCollaboration($providerManager); + Listener::register($dispatcher); + $this->registerSearchProvider($search); $this->registerTemplates(); - $context->injectFn(Closure::fromCallable([$this, 'registerNavigation'])); + $this->registerNavigation($l10n); $this->registerHooks(); } diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php index 06a17e5242b57..cd259289af363 100644 --- a/lib/private/AppFramework/Bootstrap/Coordinator.php +++ b/lib/private/AppFramework/Bootstrap/Coordinator.php @@ -32,6 +32,7 @@ use OC\Support\CrashReport\Registry; use OC_App; use OCP\AppFramework\App; +use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\QueryException; use OCP\Dashboard\IManager; @@ -173,7 +174,10 @@ public function bootApp(string $appId): void { if ($application instanceof IBootstrap) { /** @var BootContext $context */ $context = new BootContext($application->getContainer()); - $application->boot($context); + $injector = new FunctionInjector($application->getContainer(), [ + IBootContext::class => $context, + ]); + $injector->injectFn([$application, 'boot']); } } catch (QueryException $e) { $this->logger->logException($e, [ diff --git a/lib/private/AppFramework/Bootstrap/FunctionInjector.php b/lib/private/AppFramework/Bootstrap/FunctionInjector.php index 3c20701618bc1..333d0a562d4aa 100644 --- a/lib/private/AppFramework/Bootstrap/FunctionInjector.php +++ b/lib/private/AppFramework/Bootstrap/FunctionInjector.php @@ -38,8 +38,15 @@ class FunctionInjector { /** @var ContainerInterface */ private $container; - public function __construct(ContainerInterface $container) { + /** + * @var object[] + * @psalm-var array + */ + private $overrides; + + public function __construct(ContainerInterface $container, array $overrides = []) { $this->container = $container; + $this->overrides = $overrides; } public function injectFn(callable $fn) { @@ -47,6 +54,10 @@ public function injectFn(callable $fn) { return $fn(...array_map(function (ReflectionParameter $param) { // First we try by type (more likely these days) if (($type = $param->getType()) !== null) { + if (isset($this->overrides[$type->getName()])) { + return $this->overrides[$type->getName()]; + } + try { return $this->container->get($type->getName()); } catch (QueryException $ex) { diff --git a/lib/public/AppFramework/Bootstrap/IBootstrap.php b/lib/public/AppFramework/Bootstrap/IBootstrap.php index 1c509876bfe86..acfa264896b42 100644 --- a/lib/public/AppFramework/Bootstrap/IBootstrap.php +++ b/lib/public/AppFramework/Bootstrap/IBootstrap.php @@ -28,6 +28,7 @@ /** * @since 20.0.0 + * @method void boot(IBootContext $context, ...$params) Boot the application */ interface IBootstrap { @@ -37,18 +38,4 @@ interface IBootstrap { * @since 20.0.0 */ public function register(IRegistrationContext $context): void; - - /** - * Boot the application - * - * At this stage you can assume that all services are registered and the DI - * container(s) are ready to be queried. - * - * This is also the state where an optional `appinfo/app.php` was loaded. - * - * @param IBootContext $context - * - * @since 20.0.0 - */ - public function boot(IBootContext $context): void; } diff --git a/tests/lib/AppFramework/Bootstrap/FunctionInjectorTest.php b/tests/lib/AppFramework/Bootstrap/FunctionInjectorTest.php index cd2332b058862..bcc0f1ba92be8 100644 --- a/tests/lib/AppFramework/Bootstrap/FunctionInjectorTest.php +++ b/tests/lib/AppFramework/Bootstrap/FunctionInjectorTest.php @@ -81,4 +81,17 @@ public function testInjectFnByName(): void { // Nothing to assert. No errors means everything is fine. $this->addToAssertionCount(1); } + + public function testInjectWithOverride(): void { + $obj = new class() implements Foo {}; + + $injector = new FunctionInjector($this->container, [ + Foo::class => $obj, + ]); + $injector->injectFn(static function (Foo $f): void { + }); + + // Nothing to assert. No errors means everything is fine. + $this->addToAssertionCount(1); + } }