Vai al contenuto principale

Cosa sono i service provider

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.
Se vuoi approfondire come Laravel gestisce le richieste, consulta la documentazione Ciclo di vita della richiesta.

Scrivere un service provider

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.
php artisan make:provider RiakServiceProvider

Metodo register

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.
<?php

namespace 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.

Proprietà bindings e singletons

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.
<?php

namespace 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,
    ];
}

Metodo boot

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.
<?php

namespace 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.

Dependency injection nel metodo boot

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) {
        // ...
    });
}

Come registrare i service provider

Tutti i service provider vanno registrati nel file bootstrap/providers.php, che restituisce un array di nomi di classi provider.
<?php

return [
    App\Providers\AppServiceProvider::class,
];
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.
<?php

return [
    App\Providers\AppServiceProvider::class,
    App\Providers\ComposerServiceProvider::class,
];

Creazione di un service provider personalizzato

Vediamo come creare in pratica un service provider personalizzato.
1

Genera il provider

Genera un service provider con il comando Artisan.
php artisan make:provider PaymentServiceProvider
2

Effettua il binding nel metodo register

Scrivi i binding nel metodo register del provider generato.
<?php

namespace App\Providers;

use App\Contracts\PaymentGateway;
use App\Services\StripePaymentGateway;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class PaymentServiceProvider extends ServiceProvider
{
    /**
     * Registra i servizi dell'applicazione
     */
    public function register(): void
    {
        $this->app->singleton(PaymentGateway::class, function (Application $app) {
            return new StripePaymentGateway(
                config('services.stripe.secret')
            );
        });
    }

    /**
     * Avvia i servizi dell'applicazione
     */
    public function boot(): void
    {
        // Eventuale logica di avvio qui
    }
}
3

Registra in bootstrap/providers.php

Con make:provider la registrazione è automatica. Se manuale, aggiungilo.
<?php

return [
    App\Providers\AppServiceProvider::class,
    App\Providers\PaymentServiceProvider::class,
];

Provider differiti (Deferred Providers)

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.
<?php

namespace 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.

Prossimi passi

Service container

Rivedi il meccanismo del service container e i dettagli sui binding.
Ultima modifica il 13 luglio 2026