Allow IBootstrap::boot to have services injected directly

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2021-04-23 16:01:47 +02:00
parent 1a1ea4e3ea
commit 4845834468
No known key found for this signature in database
GPG Key ID: CC42AC2A7F0E56D8
4 changed files with 31 additions and 16 deletions

View File

@ -32,6 +32,7 @@ namespace OC\AppFramework\Bootstrap;
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 @@ class Coordinator {
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, [

View File

@ -38,8 +38,15 @@ class FunctionInjector {
/** @var ContainerInterface */
private $container;
public function __construct(ContainerInterface $container) {
/**
* @var object[]
* @psalm-var array<class-string, object>
*/
private $overrides;
public function __construct(ContainerInterface $container, array $overrides = []) {
$this->container = $container;
$this->overrides = $overrides;
}
public function injectFn(callable $fn) {
@ -47,6 +54,10 @@ class FunctionInjector {
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) {

View File

@ -28,6 +28,7 @@ namespace OCP\AppFramework\Bootstrap;
/**
* @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;
}

View File

@ -81,4 +81,17 @@ class FunctionInjectorTest extends TestCase {
// 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);
}
}