Skip to content
This repository was archived by the owner on May 16, 2026. It is now read-only.
This repository was archived by the owner on May 16, 2026. It is now read-only.

Recursion occurs for ProviderRegistry::getProviderFor(...) #2

Description

@tlmcclatchey

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);;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions