-
Notifications
You must be signed in to change notification settings - Fork 0
Description
If a service provider requires that a class be registered as a service, the logical thing is to check for the existence of it in the bootstrap. When calling ->supports(...) the recursion starts as it asks the service manager for the (potentially) non-instantiated instance of the dependant class, at which point it will iterate through service providers and check if the current service provider supports the class - at which point it goes back to the service manager
The current workaround, placed in the ->supports(...) method, is to check if the class name matches any of the dependent service classes and, if so, return false.
We need to find a way to have something similar to the instantiation stack on the DI library, so a specific service provider is never called recursively.
class RecursionTestServiceProvider implements ServiceProviderContract, BootstrapperContract
{
private ServiceManager $serviceManager;
#[\Override] function bootstrap(ServiceManager $serviceManager): void
{
$this->serviceManager = $serviceManager;
if (!$serviceManager->has(RecursionTestService::class))
{
throw new Exception('Why doesn\'t this throw?');
}
// WARNING: This is recursively called
}
#[\Override] public function supports(string $className): bool
{
// WARNING: This is recursively called
return $this->serviceManager->get(RecursionTestService::class)->supports($className);
}
#[\Override] public function handle(string $className, array $parameters = []): object
{
// TODO: Implement handle() method.
}
#[\Override] public function isSingletonExpected(string $className): bool
{
// TODO: Implement isSingletonExpected() method.
}
}
class RecursionTestService
{
public function supports($className): bool
{
// WARNING: This is recursively called
}
}
$serviceManager = new ServiceManager();
$serviceManager->providers->registerProvider(RecursionTestServiceProvider::class);;