How does Laravel defer multiple bindings listed in the same service provider?
I want all my repos to be listed in one service provider, but I don't want all of them downloaded at once ...
Please contact your service provider below:
class RepositoryServiceProvider extends ServiceProvider {
protected $defer = true;
public function register()
{
$this->app->bind(
'App\Repositories\Contracts\FooRepository',
'App\Repositories\SQL\FooSQLRepository');
$this->app->bind(
'App\Repositories\Contracts\BarRepository',
'App\Repositories\SQL\BarSQLRepository');
// and more to be added later...
}
public function provides()
{
// Will it defer and load all these at once? Or only the one(s) needed?
return ['App\Repositories\Contracts\FooRepository',
'App\Repositories\Contracts\BarRepository'];
}
}
According to the Laravel docs , I can defer registering bindings until needed. But does this work when I have added multiple bindings to one service provider? Specifically, I mean, will it defer and then download everything, or only download the one you want ?
source to share
Laravel will register all bindings, even if only one is required. The deferred function actually works quite simply. First, a map of records in provides()
and the actual provider is created:
Illuminate\Foundation\ProviderRepository@compileManifest
if ($instance->isDeferred())
{
foreach ($instance->provides() as $service)
{
$manifest['deferred'][$service] = $provider;
}
$manifest['when'][$provider] = $instance->when();
}
Then when make()
called in Illuminate\Foundation\Application
...
if (isset($this->deferredServices[$abstract]))
{
$this->loadDeferredProvider($abstract);
}
... and the binding matches one of the deferred providers, it will be here:
Illuminate\Foundation\Application@registerDeferredProvider
$this->register($instance = new $provider($this));
if ( ! $this->booted)
{
$this->booting(function() use ($instance)
{
$this->bootProvider($instance);
});
}
As you might say, the provider is now registered as usual, which means register()
and boot()
. If you think about it, it is not even possible to download one binding from a service provider and not enable others, because it is all done in one way.
source to share