Cos’è un Contract
I “Contracts” di Laravel sono un insieme di interfacce che definiscono i servizi principali offerti dal framework. Ad esempio, il ContractIlluminate\Contracts\Queue\Queue definisce i metodi necessari a mettere in coda i job, mentre il Contract Illuminate\Contracts\Mail\Mailer definisce i metodi necessari per l’invio di email.
Per ogni Contract il framework fornisce un’implementazione corrispondente. Laravel offre ad esempio implementazioni di code con vari driver e un mailer basato su Symfony Mailer.
Tutti i Contracts di Laravel si trovano nel loro repository GitHub dedicato. Costituisce un riferimento rapido a tutti i Contract disponibili ed è un pacchetto isolato che puoi usare quando costruisci pacchetti che si integrano con i servizi Laravel.
Un Contract è semplicemente un’interfaccia. Funziona esattamente come le interfacce di PHP. Laravel fornisce le implementazioni di queste interfacce e le inietta tramite il service container.
Differenza tra Contract e Facade
Le facade e le funzioni helper offrono un modo semplice per usare i servizi di Laravel senza dover risolvere i Contract con un type hint dal service container. Nella maggior parte dei casi, ciascuna facade ha un Contract corrispondente. Le differenze principali tra facade e Contract sono le seguenti.| Aspetto | Facade | Contract |
|---|---|---|
| Dichiarazione della dipendenza | Non necessaria (richiamabile ovunque) | Dichiarata esplicitamente nel costruttore |
| Test | Mock con shouldReceive() | Sostituzione tramite una libreria di mock standard |
| Uso principale | Uso agevole all’interno dell’applicazione | Sviluppo di pacchetti, gestione esplicita delle dipendenze |
| Leggibilità del codice | Basta una singola riga di import | Le dipendenze sono immediatamente visibili nel costruttore |
Quando usare i Contract
Scegliere tra Contract e Facade dipende dalle preferenze personali o del team. Entrambi permettono di creare applicazioni Laravel robuste e testabili. Non si escludono a vicenda: in una parte dell’applicazione puoi usare le Facade e in un’altra affidarti ai Contract. I Contract sono particolarmente utili nelle seguenti situazioni:- Quando costruisci pacchetti che si integrano con più framework PHP — Usando il pacchetto
illuminate/contractsper definire l’integrazione con i servizi Laravel, non devi richiedere l’implementazione concreta di Laravel nelcomposer.json. - Quando vuoi rendere esplicite le dipendenze — Guardando il costruttore capisci a colpo d’occhio da cosa dipende la classe.
- Quando vuoi sostituire l’implementazione — Diventa facile sostituire l’implementazione tramite il service container.
Come usare i Contract
Come si ottiene l’implementazione di un Contract? È molto semplice. Molti tipi di classi di Laravel — controller, listener di eventi, middleware, job in coda, closure di route e altre — vengono risolti tramite il service container. Per ottenere l’implementazione di un Contract basta “type-hintare” l’interfaccia nel costruttore della classe risolta. Ad esempio, guarda il seguente event listener.Creazione di Contract personalizzati
Creare i propri Contract permette di rendere chiare le dipendenze tra i componenti dell’applicazione.Collega Contract e implementazione in un service provider
Effettua il binding tra Contract e implementazione in un service provider.
Stripe a un altro provider, ti basta modificare il binding in un solo punto senza toccare il codice del controller.
Elenco dei Contract principali
Tabella di corrispondenza tra i Contract più usati e le rispettive facade (estratto).| Contract | Facade corrispondente |
|---|---|
Illuminate\Contracts\Auth\Access\Gate | Gate |
Illuminate\Contracts\Auth\Factory | Auth |
Illuminate\Contracts\Bus\Dispatcher | Bus |
Illuminate\Contracts\Cache\Factory | Cache |
Illuminate\Contracts\Cache\Repository | Cache::driver() |
Illuminate\Contracts\Config\Repository | Config |
Illuminate\Contracts\Console\Kernel | Artisan |
Illuminate\Contracts\Container\Container | App |
Illuminate\Contracts\Encryption\Encrypter | Crypt |
Illuminate\Contracts\Events\Dispatcher | Event |
Illuminate\Contracts\Filesystem\Factory | Storage |
Illuminate\Contracts\Filesystem\Filesystem | Storage::disk() |
Illuminate\Contracts\Hashing\Hasher | Hash |
Illuminate\Contracts\Mail\Mailer | Mail |
Illuminate\Contracts\Notifications\Dispatcher | Notification |
Illuminate\Contracts\Queue\Factory | Queue |
Illuminate\Contracts\Queue\Queue | Queue::connection() |
Illuminate\Contracts\Queue\ShouldQueue | — |
Illuminate\Contracts\Redis\Factory | Redis |
Illuminate\Contracts\Routing\ResponseFactory | Response |
Illuminate\Contracts\Routing\UrlGenerator | URL |
Illuminate\Contracts\Session\Session | Session::driver() |
Illuminate\Contracts\Translation\Translator | Lang |
Illuminate\Contracts\Validation\Factory | Validator |
Illuminate\Contracts\View\Factory | View |
Prossimi passi
Facade
Approfondisci il funzionamento delle facade e i loro metodi di test.