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,10 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\DI;
|
||||
|
||||
use App\Framework\Core\ValueObjects\ClassName;
|
||||
use App\Framework\Reflection\ReflectionProvider;
|
||||
use ReflectionMethod;
|
||||
use ReflectionNamedType;
|
||||
use App\Framework\Reflection\WrappedReflectionMethod;
|
||||
|
||||
/**
|
||||
* Führt Methoden auf beliebigen Klassen mit automatischer Dependency Injection aus
|
||||
@@ -13,15 +15,17 @@ final readonly class MethodInvoker
|
||||
{
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private ReflectionProvider $reflectionCache
|
||||
) {}
|
||||
private ReflectionProvider $reflectionProvider
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt eine Methode auf einer Klasse aus und löst alle Parameter automatisch auf
|
||||
*/
|
||||
public function invoke(string $className, string $methodName, array $overrides = []): mixed
|
||||
public function invoke(ClassName $className, string $methodName, array $overrides = []): mixed
|
||||
{
|
||||
$instance = $this->container->get($className);
|
||||
$instance = $this->container->get($className->getFullyQualified());
|
||||
|
||||
return $this->invokeOn($instance, $methodName, $overrides);
|
||||
}
|
||||
|
||||
@@ -30,25 +34,28 @@ final readonly class MethodInvoker
|
||||
*/
|
||||
public function invokeOn(object $instance, string $methodName, array $overrides = []): mixed
|
||||
{
|
||||
$reflection = $this->reflectionCache->getClass($instance::class);
|
||||
$className = ClassName::fromObject($instance);
|
||||
$reflection = $this->reflectionProvider->getClass($className);
|
||||
|
||||
if (!$reflection->hasMethod($methodName)) {
|
||||
if (! $reflection->hasMethod($methodName)) {
|
||||
throw new \InvalidArgumentException(
|
||||
"Method $methodName does not exist on class $instance::class"
|
||||
"Method $methodName does not exist on class " . $instance::class
|
||||
);
|
||||
}
|
||||
|
||||
$method = $this->reflectionCache->getMethod($instance::class, $methodName);
|
||||
// Framework WrappedReflectionMethod verwenden
|
||||
$method = $this->reflectionProvider->getMethod($className, $methodName);
|
||||
$nativeMethod = $this->reflectionProvider->getNativeMethod($className, $methodName);
|
||||
|
||||
if (!$method->isPublic()) {
|
||||
if (! $nativeMethod->isPublic()) {
|
||||
throw new \InvalidArgumentException(
|
||||
"Method $methodName on class $instance::class is not public"
|
||||
"Method $methodName on class " . $instance::class . " is not public"
|
||||
);
|
||||
}
|
||||
|
||||
$parameters = $this->resolveMethodParameters($method, $overrides);
|
||||
$parameters = $this->resolveMethodParameters($className, $methodName, $overrides);
|
||||
|
||||
return $method->invokeArgs($instance, $parameters);
|
||||
return $nativeMethod->invokeArgs($instance, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,69 +63,77 @@ final readonly class MethodInvoker
|
||||
*/
|
||||
public function invokeStatic(string $className, string $methodName, array $overrides = []): mixed
|
||||
{
|
||||
$reflection = $this->reflectionCache->getClass($className);
|
||||
$classNameObj = ClassName::create($className);
|
||||
$reflection = $this->reflectionProvider->getClass($classNameObj);
|
||||
|
||||
if (!$reflection->hasMethod($methodName)) {
|
||||
if (! $reflection->hasMethod($methodName)) {
|
||||
throw new \InvalidArgumentException(
|
||||
"Method '{$methodName}' does not exist on class '{$className}'"
|
||||
);
|
||||
}
|
||||
|
||||
$method = $this->reflectionCache->getMethod($className, $methodName);
|
||||
// Framework WrappedReflectionMethod verwenden
|
||||
$method = $this->reflectionProvider->getMethod($classNameObj, $methodName);
|
||||
$nativeMethod = $this->reflectionProvider->getNativeMethod($classNameObj, $methodName);
|
||||
|
||||
if (!$method->isStatic()) {
|
||||
if (! $nativeMethod->isStatic()) {
|
||||
throw new \InvalidArgumentException(
|
||||
"Method '{$methodName}' on class '{$className}' is not static"
|
||||
);
|
||||
}
|
||||
|
||||
$parameters = $this->resolveMethodParameters($method, $overrides);
|
||||
$parameters = $this->resolveMethodParameters($classNameObj, $methodName, $overrides);
|
||||
|
||||
return $method->invokeArgs(null, $parameters);
|
||||
return $nativeMethod->invokeArgs(null, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löst alle Parameter einer Methode auf
|
||||
*/
|
||||
private function resolveMethodParameters(ReflectionMethod $method, array $overrides): array
|
||||
private function resolveMethodParameters(ClassName $className, string $methodName, array $overrides): array
|
||||
{
|
||||
$parameters = [];
|
||||
|
||||
foreach ($method->getParameters() as $param) {
|
||||
// Framework ParameterCollection verwenden
|
||||
$methodParameters = $this->reflectionProvider->getMethodParameters($className, $methodName);
|
||||
|
||||
foreach ($methodParameters as $param) {
|
||||
$paramName = $param->getName();
|
||||
|
||||
// Override-Werte haben Priorität
|
||||
if (array_key_exists($paramName, $overrides)) {
|
||||
$parameters[] = $overrides[$paramName];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Type-based injection
|
||||
$type = $param->getType();
|
||||
|
||||
if ($type instanceof ReflectionNamedType && !$type->isBuiltin()) {
|
||||
$typeName = $type->getName();
|
||||
// Type-based injection mit Framework API
|
||||
$typeName = $param->getTypeName();
|
||||
|
||||
if ($typeName !== null && ! $param->isBuiltin()) {
|
||||
if ($this->container->has($typeName)) {
|
||||
$parameters[] = $this->container->get($typeName);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Default-Werte verwenden
|
||||
if ($param->isDefaultValueAvailable()) {
|
||||
if ($param->hasDefaultValue()) {
|
||||
$parameters[] = $param->getDefaultValue();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Nullable Parameter
|
||||
if ($type && $type->allowsNull()) {
|
||||
if ($param->allowsNull()) {
|
||||
$parameters[] = null;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(
|
||||
"Cannot resolve parameter '{$paramName}' for method '{$method->getName()}' on class '{$method->getDeclaringClass()->getName()}'"
|
||||
"Cannot resolve parameter '{$paramName}' for method '{$methodName}' on class '{$className->getFullyQualified()}'"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user