Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolving() events on interfaces are called twice #23699

Closed
tomlankhorst opened this issue Mar 26, 2018 · 5 comments
Closed

resolving() events on interfaces are called twice #23699

tomlankhorst opened this issue Mar 26, 2018 · 5 comments
Labels

Comments

@tomlankhorst
Copy link
Contributor

tomlankhorst commented Mar 26, 2018

In L5.5, 5.6 I experience an issue with resolving callbacks on dependencies registered in the container with an interface class as abstract. A demonstration:

Having some interface

IBar {}

and an implementation

Foo implements IBar {}

registered (here as a singleton) in the container

app()->singleton( IBar::class, Foo::class );

with a resolving callback

app()->resolving( IBar::class, $callback );

fires $callback twice when the abstract is resolved!

This is probably because:

  1. When the abstract IBar resolves, it triggers the callback
  2. To resolve IBar, Foo must be constructed. As Foo implements IBar, it triggers the resolving event too!

This problem can be omitted when avoiding Laravel's container to build Foo by registering a callback instead:

app()->singleton( IBar::class, f(){ return new Foo; } )

But this abolishes the ease of automatic dependency injection.

So... can we solve this issue by not firing the resolving() callback when we are building the implementation of an interface that the callback is registered for?

@sisve
Copy link
Contributor

sisve commented Mar 26, 2018

There has been some attempts to fix this previously in #23290 but it wasn't merged. Perhaps send a PR with your suggested changes?

@tomlankhorst
Copy link
Contributor Author

tomlankhorst commented Mar 26, 2018

Fine, I'll submit a PR these days that will address this issue.

This test triggers the problem:

    public function testResolvingCallbacksAreCalledOnceForImplementations()
    {
        $invocations = 0;
        $container = new Container;
        $container->resolving( IContainerContractStub::class, function( ) use ( &$invocations ) {
            $invocations++;
        } );
        $container->bind(IContainerContractStub::class, ContainerImplementationStub::class );

        $this->assertEquals( 0, $invocations );
        $container->make( IContainerContractStub::class );
        $this->assertEquals( 1, $invocations );
    }

@tomlankhorst
Copy link
Contributor Author

"... these days..."
#23701

@taylorotwell
Copy link
Member

Fixed in 5.8.

@hkodavid
Copy link

The bug is still in 5.8.12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants