Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
@@ -1,27 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\DI;
|
||||
|
||||
use App\Framework\Core\ValueObjects\ClassName;
|
||||
use App\Framework\DI\Exceptions\CyclicDependencyException;
|
||||
use App\Framework\DI\Exceptions\LazyLoadingException;
|
||||
use App\Framework\Reflection\CachedReflectionProvider;
|
||||
use App\Framework\Reflection\ReflectionProvider;
|
||||
|
||||
use Throwable;
|
||||
|
||||
final class DefaultContainer implements Container
|
||||
{
|
||||
/** @var class-string[] */
|
||||
private array $resolving = [];
|
||||
|
||||
private readonly DependencyResolver $dependencyResolver;
|
||||
|
||||
private readonly SingletonDetector $singletonDetector;
|
||||
|
||||
private readonly LazyInstantiator $lazyInstantiator;
|
||||
|
||||
public readonly MethodInvoker $invoker;
|
||||
|
||||
public function __construct(
|
||||
private readonly InstanceRegistry $instances = new InstanceRegistry(),
|
||||
private readonly BindingRegistry $bindings = new BindingRegistry(),
|
||||
private readonly ReflectionProvider $reflectionProvider = new CachedReflectionProvider(),
|
||||
){
|
||||
) {
|
||||
$this->dependencyResolver = new DependencyResolver($this->reflectionProvider, $this);
|
||||
$this->singletonDetector = new SingletonDetector($this->reflectionProvider, $this->instances);
|
||||
$this->lazyInstantiator = new LazyInstantiator(
|
||||
@@ -31,12 +38,13 @@ final class DefaultContainer implements Container
|
||||
$this->invoker = new MethodInvoker($this, $this->reflectionProvider);
|
||||
|
||||
$this->registerSelf();
|
||||
$this->instance(ReflectionProvider::class, $this->reflectionProvider);
|
||||
}
|
||||
|
||||
public function bind(string $abstract, callable|string|object $concrete): void
|
||||
{
|
||||
$this->bindings->bind($abstract, $concrete);
|
||||
$this->clearCaches($abstract);
|
||||
$this->clearCaches(ClassName::create($abstract));
|
||||
}
|
||||
|
||||
public function singleton(string $abstract, callable|string|object $concrete): void
|
||||
@@ -51,15 +59,16 @@ final class DefaultContainer implements Container
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
* @param class-string<T> $class
|
||||
* @return T
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get(string $class): object
|
||||
{
|
||||
// Bereits instanziierte Objekte zurückgeben
|
||||
if ($this->instances->hasSingleton($class)) {
|
||||
return $this->instances->getSingleton($class);
|
||||
$singleton = $this->instances->getSingleton($class);
|
||||
if ($singleton !== null) {
|
||||
return $singleton;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->instances->hasInstance($class)) {
|
||||
@@ -71,7 +80,7 @@ final class DefaultContainer implements Container
|
||||
try {
|
||||
return $this->lazyInstantiator->createLazyInstance($class);
|
||||
} catch (Throwable $e) {
|
||||
if (!$e instanceof LazyLoadingException) {
|
||||
if (! $e instanceof LazyLoadingException) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
@@ -80,6 +89,11 @@ final class DefaultContainer implements Container
|
||||
return $this->createInstance($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
* @param class-string<T> $class
|
||||
* @return T
|
||||
*/
|
||||
private function createInstance(string $class): object
|
||||
{
|
||||
if (in_array($class, $this->resolving, true)) {
|
||||
@@ -94,7 +108,7 @@ final class DefaultContainer implements Container
|
||||
try {
|
||||
$instance = $this->buildInstance($class);
|
||||
|
||||
if ($this->singletonDetector->isSingleton($class)) {
|
||||
if ($this->singletonDetector->isSingleton(ClassName::create($class))) {
|
||||
$this->instances->setSingleton($class, $instance);
|
||||
} else {
|
||||
$this->instances->setInstance($class, $instance);
|
||||
@@ -108,14 +122,15 @@ final class DefaultContainer implements Container
|
||||
|
||||
private function buildInstance(string $class): object
|
||||
{
|
||||
$className = ClassName::create($class);
|
||||
if ($this->bindings->hasBinding($class)) {
|
||||
return $this->resolveBinding($class, $this->bindings->getBinding($class));
|
||||
}
|
||||
|
||||
$reflection = $this->reflectionProvider->getClass($class);
|
||||
$dependencies = $this->dependencyResolver->resolveDependencies($class);
|
||||
$reflection = $this->reflectionProvider->getClass($className);
|
||||
$dependencies = $this->dependencyResolver->resolveDependencies($className);
|
||||
|
||||
return $reflection->newInstanceArgs($dependencies);
|
||||
return $reflection->newInstance(...$dependencies->toArray());
|
||||
}
|
||||
|
||||
private function resolveBinding(string $class, callable|string|object $concrete): object
|
||||
@@ -127,24 +142,27 @@ final class DefaultContainer implements Container
|
||||
};
|
||||
}
|
||||
|
||||
/** @param class-string $class */
|
||||
public function has(string $class): bool
|
||||
{
|
||||
return $this->instances->hasSingleton($class)
|
||||
|| $this->instances->hasInstance($class)
|
||||
|| $this->bindings->hasBinding($class)
|
||||
|| class_exists($class);
|
||||
|| (! empty($class) && ClassName::create($class)->exists() && $this->reflectionProvider->getClass(ClassName::create($class))->isInstantiable());
|
||||
}
|
||||
|
||||
/** @param class-string $class */
|
||||
public function forget(string $class): void
|
||||
{
|
||||
$this->instances->forget($class);
|
||||
$this->bindings->forget($class);
|
||||
$this->clearCaches($class);
|
||||
$this->clearCaches(ClassName::create($class));
|
||||
}
|
||||
|
||||
public function flush(): void
|
||||
{
|
||||
$this->instances->flush();
|
||||
$this->bindings->flush();
|
||||
$this->reflectionProvider->flush();
|
||||
$this->dependencyResolver->flushCache();
|
||||
$this->lazyInstantiator->flushFactories();
|
||||
@@ -161,14 +179,23 @@ final class DefaultContainer implements Container
|
||||
);
|
||||
}
|
||||
|
||||
private function clearCaches(string $class): void
|
||||
/**
|
||||
* Get all registered service IDs (for debugging/admin)
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getServiceIds(): array
|
||||
{
|
||||
$this->reflectionProvider->forget($class);
|
||||
$this->dependencyResolver->clearCache($class);
|
||||
$this->lazyInstantiator->forgetFactory($class);
|
||||
return array_keys($this->getRegisteredServices());
|
||||
}
|
||||
|
||||
private function registerSelf():void
|
||||
private function clearCaches(ClassName $className): void
|
||||
{
|
||||
$this->reflectionProvider->forget($className);
|
||||
$this->dependencyResolver->clearCache($className);
|
||||
$this->lazyInstantiator->forgetFactory($className->getFullyQualified());
|
||||
}
|
||||
|
||||
private function registerSelf(): void
|
||||
{
|
||||
$this->instances->setSingleton(self::class, $this);
|
||||
$this->instances->setSingleton(DefaultContainer::class, $this);
|
||||
|
||||
Reference in New Issue
Block a user