I service provider sono il fulcro del bootstrapping dell’intera applicazione Laravel. Sia la tua applicazione sia tutti i servizi core di Laravel vengono avviati tramite service provider.Per “bootstrap” si intende registrare vari elementi: binding sul service container, event listener, middleware, route e altro. I service provider sono il luogo centrale di configurazione dell’applicazione.Laravel usa internamente molti service provider per fare il bootstrap dei servizi core come mailer, code e cache. Molti di questi provider sono “deferred”: non vengono caricati per ogni richiesta ma solo quando i servizi forniti sono effettivamente necessari.Tutti i service provider definiti dall’utente si registrano nel file bootstrap/providers.php.
Tutti i service provider estendono Illuminate\Support\ServiceProvider. La maggior parte include i metodi register e boot.Per generarne uno nuovo usa il comando Artisan make:provider. Laravel lo registra automaticamente in bootstrap/providers.php.
Nel metodo register esegui solo binding sul service container. Non tentare di registrare qui event listener, route o altre funzionalità: potresti usare per errore servizi forniti da provider non ancora caricati.
<?phpnamespace App\Providers;use App\Services\Riak\Connection;use Illuminate\Contracts\Foundation\Application;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider{ /** * Registra i servizi dell'applicazione */ public function register(): void { $this->app->singleton(Connection::class, function (Application $app) { return new Connection(config('riak')); }); }}
Nei metodi del service provider puoi sempre accedere al service container tramite $this->app.
Se registri molti binding semplici, invece di scriverli uno per uno puoi usare le proprietà bindings e singletons. Quando il framework carica il provider, controlla automaticamente queste proprietà e registra i binding.
<?phpnamespace App\Providers;use App\Contracts\DowntimeNotifier;use App\Contracts\ServerProvider;use App\Services\DigitalOceanServerProvider;use App\Services\PingdomDowntimeNotifier;use App\Services\ServerToolsProvider;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{ /** * Tutti i binding del container da registrare * * @var array */ public $bindings = [ ServerProvider::class => DigitalOceanServerProvider::class, ]; /** * Tutti i singleton del container da registrare * * @var array */ public $singletons = [ DowntimeNotifier::class => PingdomDowntimeNotifier::class, ServerProvider::class => ServerToolsProvider::class, ];}
Se in un service provider devi registrare un view composer, fallo nel metodo boot. Questo metodo viene chiamato dopo che tutti gli altri service provider sono stati registrati, quindi hai accesso a tutti gli altri servizi già registrati dal framework.
<?phpnamespace App\Providers;use Illuminate\Support\Facades\View;use Illuminate\Support\ServiceProvider;class ComposerServiceProvider extends ServiceProvider{ /** * Avvia i servizi dell'applicazione */ public function boot(): void { View::composer('view', function () { // ... }); }}
Non confondere i ruoli di register e boot. register è solo per registrare binding; boot è per l’inizializzazione dei servizi e altri setup.
Anche nel metodo boot puoi usare il type hint per iniettare dipendenze. Il service container inietterà automaticamente quelle richieste.
use Illuminate\Contracts\Routing\ResponseFactory;/** * Avvia i servizi dell'applicazione */public function boot(ResponseFactory $response): void{ $response->macro('serialized', function (mixed $value) { // ... });}
In Laravel 13, i service provider si registrano in bootstrap/providers.php invece che nell’array providers di config/app.php. Il comando make:provider li aggiunge automaticamente.
Quando esegui make:provider, Laravel aggiunge automaticamente il provider al file. Se crei manualmente una classe provider, aggiungila manualmente all’array.
Se un provider registra solo binding sul service container, puoi ritardarne la registrazione fino a quando i binding non sono realmente necessari. Ritardare il caricamento di questi provider evita di caricarli dal filesystem a ogni richiesta e migliora le prestazioni.Per creare un provider differito implementa l’interfaccia \Illuminate\Contracts\Support\DeferrableProvider e definisci il metodo provides. Il metodo provides restituisce i binding sul service container che il provider registra.
<?phpnamespace App\Providers;use App\Services\Riak\Connection;use Illuminate\Contracts\Foundation\Application;use Illuminate\Contracts\Support\DeferrableProvider;use Illuminate\Support\ServiceProvider;class RiakServiceProvider extends ServiceProvider implements DeferrableProvider{ /** * Registra i servizi dell'applicazione */ public function register(): void { $this->app->singleton(Connection::class, function (Application $app) { return new Connection(config('riak')); }); } /** * Ottiene i servizi forniti dal provider * * @return array<int, string> */ public function provides(): array { return [Connection::class]; }}
I provider differiti sono adatti a servizi usati solo in funzionalità specifiche dell’applicazione. Evitando di caricare servizi inutili ottimizzi le prestazioni.