Questa pagina presuppone la conoscenza delle basi dello sviluppo di pacchetti. Ti consigliamo di leggere prima le nozioni di base sui service provider.
Perché servono i deferred provider
I service provider normali chiamanoregister() e boot() a ogni richiesta. Inizializzare ogni volta funzionalità che non vengono usate in tutte le pagine — come invio email, code o cache — è uno spreco.
L’interfaccia DeferrableProvider
Illuminate\Contracts\Support\DeferrableProvider è un’interfaccia semplice con un solo metodo: provides().
Implementazione di base
L’implementazione di un deferred provider si articola in tre passi.1
Implementare DeferrableProvider
2
Registrare i servizi in register()
Come in un provider normale, i bind vanno in
register().3
Restituire i servizi registrati da provides()
provides() deve restituire tutti i servizi registrati in register(). Da questa lista Laravel decide “quando richiedere quale servizio caricare questo provider”.Meccanismo del service manifest
All’avvio Laravel genera un file manifest chiamatobootstrap/cache/services.php. In esso è memorizzata la lista dei servizi forniti dai deferred provider.
Flusso del funzionamento interno
Importanza del metodo provides()
Se inprovides() manca una registrazione, quel servizio non verrà mai risolto.
$bindings / $singletons: vanno anch’esse elencate in provides().
Limitazioni dei deferred provider
I deferred provider sono adatti quando l’unico scopo è registrare binding nel container. Non si può differire un provider che inboot() fa cose come queste.
Metodo when() — registrazione via trigger evento
Con il metodowhen() puoi registrare il provider al verificarsi di eventi specifici. Utile per provider necessari solo in contesti specifici, come l’elaborazione dei job.
when() viene emesso, il provider viene caricato anche se il servizio non è stato risolto direttamente.
Utilizzo nello sviluppo di pacchetti
Anche nella distribuzione come pacchetto di terze parti, i deferred provider contribuiscono alle performance dell’applicazione dell’utente.Pattern consigliato
mergeConfigFrom() verifica internamente se la configurazione è in cache, quindi può essere chiamato in sicurezza dentro register() di un deferred provider. Se la configurazione è già in cache, non fa nulla.Isolare la registrazione dei comandi Artisan con runningInConsole()
La registrazione dei comandi serve solo all’avvio di Artisan, quindi usa un branch con runningInConsole(). Se il provider che fornisce i comandi è differito, ricorda di includere le classi dei comandi in provides() oppure predisponi un provider dedicato ai soli comandi.
Esempi nel core di Laravel
Molti dei provider core di Laravel sono differiti. Il design è pensato per evitare di caricare in modo immediato tutti i servizi che non vengono usati a ogni richiesta.
In un’applicazione fatta solo di endpoint API può capitare che
MailServiceProvider o BroadcastServiceProvider non vengano mai caricati durante una richiesta.
Criteri per decidere se differire
Servizi adatti al deferring
Servizi adatti al deferring
- Servizi non usati in tutte le richieste (mail, report, client di API esterne, ecc.)
- Servizi la cui inizializzazione richiede connessioni esterne o letture di file
- Servizi con grafi di oggetti pesanti
- Provider che offrono comandi usati solo da CLI
Servizi NON adatti al deferring
Servizi NON adatti al deferring
- Provider che registrano rotte (con
loadRoutesFrom, ecc.) - Provider che registrano middleware o exception handler sempre attivi
- Provider che registrano global scope o observer Eloquent
- Servizi leggeri usati nella maggior parte delle richieste (l’overhead del deferring sarebbe maggiore)
Pagine correlate
Nozioni di sviluppo dei pacchetti
Come sviluppare pacchetti Laravel imperniati sui service provider.
Gestire la compatibilità tra versioni dei pacchetti
Strategie di manutenzione dei pacchetti per gli upgrade major di Laravel e PHP.