> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Service provider

> Come registrare e avviare i servizi dell'applicazione usando i service provider di Laravel.

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

```mermaid theme={null}
flowchart TD
    A["Avvio dell'applicazione"] --> B["Legge bootstrap/providers.php"]
    B --> C["Istanzia tutti i provider"]
    C --> D["Esegue register() di tutti i provider<br>Solo registrazione dei binding sul service container"]
    D --> E["Esegue boot() di tutti i provider<br>View composer, event listener, ecc."]
    E --> F["Applicazione pronta<br>Inizio della gestione delle richieste"]
```

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

<Info>
  Se vuoi approfondire come Laravel gestisce le richieste, consulta la documentazione [Ciclo di vita della richiesta](https://laravel.com/docs/lifecycle).
</Info>

## 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`.

```shell theme={null}
php artisan make:provider RiakServiceProvider
```

### Metodo register

Nel metodo `register` esegui solo binding sul [service container](/it/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 theme={null}
<?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 theme={null}
<?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](https://laravel.com/docs/views#view-composers), 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 theme={null}
<?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 () {
            // ...
        });
    }
}
```

<Warning>
  Non confondere i ruoli di `register` e `boot`. `register` è solo per registrare binding; `boot` è per l'inizializzazione dei servizi e altri setup.
</Warning>

#### Dependency injection nel metodo boot

Anche nel metodo `boot` puoi usare il type hint per iniettare dipendenze. Il [service container](/it/service-container) inietterà automaticamente quelle richieste.

```php theme={null}
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 theme={null}
<?php

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

<Info>
  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.
</Info>

Quando esegui `make:provider`, Laravel aggiunge automaticamente il provider al file. Se crei manualmente una classe provider, aggiungila manualmente all'array.

```php theme={null}
<?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.

<Steps>
  <Step title="Genera il provider">
    Genera un service provider con il comando Artisan.

    ```shell theme={null}
    php artisan make:provider PaymentServiceProvider
    ```
  </Step>

  <Step title="Effettua il binding nel metodo register">
    Scrivi i binding nel metodo `register` del provider generato.

    ```php theme={null}
    <?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
        }
    }
    ```
  </Step>

  <Step title="Registra in bootstrap/providers.php">
    Con `make:provider` la registrazione è automatica. Se manuale, aggiungilo.

    ```php theme={null}
    <?php

    return [
        App\Providers\AppServiceProvider::class,
        App\Providers\PaymentServiceProvider::class,
    ];
    ```
  </Step>
</Steps>

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

```mermaid theme={null}
flowchart TD
    A["Avvio dell'applicazione"] --> B["Carica e inizializza i provider normali"]
    B --> C["I provider differiti registrano solo<br>l'elenco dei servizi forniti"]
    C --> D["Gestione della richiesta"]
    D --> E{{"È richiesto un servizio<br>di un provider differito?"}}
    E -->|"No"| F["Il provider non viene caricato<br>Risparmi memoria ed elaborazione"]
    E -->|"Sì"| G["Carica il provider al momento"]
    G --> H["Esegui register()"]
    H --> I["Fornisci il servizio dal container"]
```

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 theme={null}
<?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];
    }
}
```

<Tip>
  I provider differiti sono adatti a servizi usati solo in funzionalità specifiche dell'applicazione. Evitando di caricare servizi inutili ottimizzi le prestazioni.
</Tip>

## Prossimi passi

<Card title="Service container" icon="box" href="/it/service-container">
  Rivedi il meccanismo del service container e i dettagli sui binding.
</Card>


## Related topics

- [Ciclo di vita della richiesta](/it/lifecycle.md)
- [Service provider differiti](/it/advanced/deferred-provider.md)
- [Service Container](/it/service-container.md)
- [FAQ sulla nuova struttura dell'app da Laravel 11](/it/advanced/app-structure-faq.md)
- [Creare un provider personalizzato per l'AI SDK](/it/advanced/ai-sdk-custom-provider.md)
