Skip to content

Commit

Permalink
Merge branch 'bugfix/fix-loading-deferred-providers-for-binding-inter…
Browse files Browse the repository at this point in the history
…faces-and-implementations' of https://github.com/lprzybylek/framework into lprzybylek-bugfix/fix-loading-deferred-providers-for-binding-interfaces-and-implementations
  • Loading branch information
taylorotwell committed Feb 28, 2020
2 parents 6979b11 + 1b6b99a commit cba2b53
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/Illuminate/Foundation/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -769,11 +769,40 @@ public function make($abstract, array $parameters = [])
{
$abstract = $this->getAlias($abstract);

$this->loadDeferredProviderIfNeeded($abstract);

return parent::make($abstract, $parameters);
}

/**
* Load deferred provider if $abstract is deferred service and instance was not loaded.
*
* @param string $abstract
*/
private function loadDeferredProviderIfNeeded($abstract)
{
if ($this->isDeferredService($abstract) && ! isset($this->instances[$abstract])) {
$this->loadDeferredProvider($abstract);
}
}

return parent::make($abstract, $parameters);
/**
* Resolve the given type from the container.
*
* (Overriding Container::resolve)
*
* @param string $abstract
* @param array $parameters
* @param bool $raiseEvents
* @return mixed
*/
protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{
$abstract = $this->getAlias($abstract);

$this->loadDeferredProviderIfNeeded($abstract);

return parent::resolve($abstract, $parameters, $raiseEvents);
}

/**
Expand Down
49 changes: 49 additions & 0 deletions tests/Foundation/FoundationApplicationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ public function testSingleProviderCanProvideMultipleDeferredServices()
$this->assertSame('foobar', $app->make('bar'));
}

public function testDeferredServiceIsLoadedWhenAccessingImplementationThroughInterface()
{
$app = new Application;
$app->setDeferredServices([
SampleInterface::class => InterfaceToImplementationDeferredServiceProvider::class,
SampleImplementation::class => SampleImplementationDeferredServiceProvider::class,
]);
$instance = $app->make(SampleInterface::class);
$this->assertEquals($instance->getPrimitive(), 'foo');
}

public function testEnvironment()
{
$app = new Application;
Expand Down Expand Up @@ -473,6 +484,44 @@ public function register()
}
}

interface SampleInterface
{
public function getPrimitive();
}

class SampleImplementation implements SampleInterface
{
private $primitive;

public function __construct($primitive)
{
$this->primitive = $primitive;
}

public function getPrimitive()
{
return $this->primitive;
}
}

class InterfaceToImplementationDeferredServiceProvider extends ServiceProvider implements DeferrableProvider
{
public function register()
{
$this->app->bind(SampleInterface::class, SampleImplementation::class);
}
}

class SampleImplementationDeferredServiceProvider extends ServiceProvider implements DeferrableProvider
{
public function register()
{
$this->app->when(SampleImplementation::class)->needs('$primitive')->give(function () {
return 'foo';
});
}
}

class ApplicationFactoryProviderStub extends ServiceProvider implements DeferrableProvider
{
public function register()
Expand Down

0 comments on commit cba2b53

Please sign in to comment.