Laravel deferred service provider `provides` not being called
Short answer:
Your compiled manifest file is already compiled by framework.
On the first time when Laravel build the application (and resolves all of services providers in IoC container)
it writes to cached file named services.php (that is, the manifest file, placed in: bootstrap/cache/services.php
).
So, if you clear the compiled via php artisan clear-compiled
command it should force framework to rebuild the manifest file and you could to note that provides
method is called.
On the next calls/requests provides
method is not called anymore.
The sequence of framework boot is nearly like this:
//public/index.php
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
\Illuminate\Foundation\Http\Kernel::__construct();
\Illuminate\Foundation\Http\Kernel::handle();
\Illuminate\Foundation\Http\Kernel::sendRequestThroughRouter();
\Illuminate\Foundation\Http\Kernel::bootstrap();
\Illuminate\Foundation\Application::bootstrapWith();
# where $bootstrapper is a item from \Illuminate\Foundation\Http\Kernel::$bootstrappers
# and $this is instance of \Illuminate\Foundation\Application
\Illuminate\Foundation\Application::make($bootstrapper)->bootstrap($this);
One of bootstrappers is Illuminate\Foundation\Bootstrap\RegisterProviders
which
invokes \Illuminate\Foundation\Application::registerConfiguredProviders()
and then invokes
\Illuminate\Foundation\ProviderRepository::__construct()
and finally:
\Illuminate\Foundation\ProviderRepository::load()
When \Illuminate\Foundation\ProviderRepository::load()
is called all services providers is registered and
\Illuminate\Support\ServiceProvider::provides()
are called also well.
And here is the snippet you should know (from \Illuminate\Foundation\ProviderRepository::load
):
/**
* Register the application service providers.
*
* @param array $providers
* @return void
*/
public function load(array $providers)
{
$manifest = $this->loadManifest();
// First we will load the service manifest, which contains information on all
// service providers registered with the application and which services it
// provides. This is used to know which services are "deferred" loaders.
if ($this->shouldRecompile($manifest, $providers)) {
$manifest = $this->compileManifest($providers);
}
// Next, we will register events to load the providers for each of the events
// that it has requested. This allows the service provider to defer itself
// while still getting automatically loaded when a certain event occurs.
foreach ($manifest['when'] as $provider => $events) {
$this->registerLoadEvents($provider, $events);
}
// We will go ahead and register all of the eagerly loaded providers with the
// application so their services can be registered with the application as
// a provided service. Then we will set the deferred service list on it.
foreach ($manifest['eager'] as $provider) {
$this->app->register($this->createProvider($provider));
}
$this->app->addDeferredServices($manifest['deferred']);
}
\Illuminate\Foundation\ProviderRepository::compileManifest()
is the place where your provides()
method is performed.