thephpleague / container

Small but powerful dependency injection container
http://container.thephpleague.com
MIT License
843 stars 102 forks source link

Extends causing an infinite loop #219

Closed pcoutinho closed 3 years ago

pcoutinho commented 3 years ago

Hi,

I think I may have found an infinite loop while organizing my service providers. If I have ServiceProvider A and B and I define a binding on A and try to extend it on B it causes an infinite loop.

Am I using extends wrong? I think it's the way it keeps searching for other Providers that provide the same service, and it enters a loop. This makes the "extend" functionality a bit useless for me.

I'll try to debug more, but here is a test case for it. I'm running version 3.3.3

class ContainerTest extends TestCase
{
    public function test_container_works()
    {
        /** @var Container $container */
        $container = new Container();

        $container->addServiceProvider(new ServiceProviderA());
        $container->addServiceProvider(new ServiceProviderB());

        $container->get(Renderer::class);
    }
}

class ServiceProviderA extends AbstractServiceProvider
{
    protected $provides = [
        Renderer::class,
    ];

    public function register(): void
    {
        $container = $this->getContainer();

        $container->share(Renderer::class, CompositeRenderer::class);
    }
}

class ServiceProviderB extends AbstractServiceProvider
{
    protected $provides = [
        Renderer::class,
    ];

    public function register(): void
    {
        $container = $this->getContainer();

        $container->extend(Renderer::class)
            ->addMethodCall('addRenderer', [new DomainExceptionRenderer()]);
    }
}
philipobenito commented 3 years ago

Merged fix, preparing release