1. Conceptos de arquitectura
  2. Proveedores de Servicios

Introducción

Los proveedores de servicios son el lugar central de toda la carga inicial de la aplicación Laravel. Tu aplicación propia, así como todos los servicios principales de Laravel, se cargan a través de proveedores de servicios.

Pero, ¿a qué nos referimos con "inicializado"? En general, nos referimos a registrar cosas, como registros en el contenedor de servicios, oyentes de eventos, middleware e incluso rutas. Los proveedores de servicios son el lugar central para configurar tu aplicación.

Si abres el archivo config/app.php incluido con Laravel, verás una matriz providers. Estas son todas las clases de proveedores de servicios que se cargarán para tu aplicación. Por defecto, se listan en esta matriz un conjunto de proveedores de servicios principales de Laravel. Estos proveedores inicializan los componentes principales de Laravel, como el envío de correos, la cola, la caché y otros. Muchos de estos proveedores son proveedores "diferidos", lo que significa que no se cargarán en cada solicitud, sino solo cuando realmente se necesiten los servicios que proporcionan.

En esta descripción general, aprenderás cómo escribir tus propios proveedores de servicios y registrarlos en tu aplicación Laravel.

Nota Si deseas obtener más información sobre cómo maneja Laravel las solicitudes y cómo funciona internamente, consulta nuestra documentación sobre el ciclo de vida de las solicitudes.

Escribir Proveedores de Servicios

Todos los proveedores de servicios extienden la clase Illuminate\Support\ServiceProvider. La mayoría de los proveedores de servicios contienen un método register y un método boot. Dentro del método register, solo debes vincular cosas en el contenedor de servicios. Nunca debes intentar registrar oyentes de eventos, rutas u otra funcionalidad dentro del método register.

El CLI de Artisan puede generar un nuevo proveedor mediante el comando make:provider:

php artisan make:provider RiakServiceProvider

El Método Register

Como se mencionó anteriormente, dentro del método register, solo debes vincular cosas en el contenedor de servicios. Nunca debes intentar registrar oyentes de eventos, rutas u otra funcionalidad dentro del método register. De lo contrario, podrías usar accidentalmente un servicio que es proporcionado por un proveedor de servicios que aún no se ha cargado.

Veamos un proveedor de servicios básico. Dentro de cualquiera de los métodos de tu proveedor de servicios, siempre tienes acceso a la propiedad $app, que proporciona acceso al contenedor de servicios:

<?php
 
namespace App\Providers;
 
use App\Services\Riak\Connection;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;
 
class RiakServiceProvider extends ServiceProvider
{
/**
* Registra cualquier servicio de la aplicación.
*/
public function register(): void
{
$this->app->singleton(Connection::class, function (Application $app) {
return new Connection(config('riak'));
});
}
}

Este proveedor de servicios solo define un método register y utiliza ese método para definir una implementación de App\Services\Riak\Connection en el contenedor de servicios. Si aún no estás familiarizado con el contenedor de servicios de Laravel, consulta su documentación.

Las Propiedades bindings y singletons

Si tu proveedor de servicios registra muchos enlaces simples, es posible que desees usar las propiedades bindings y singletons en lugar de registrar manualmente cada enlace del contenedor. Cuando el framework carga el proveedor de servicios, automáticamente verificará estas propiedades y registrará sus enlaces:

<?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
{
/**
* Todos los enlaces de contenedor que deben registrarse.
*
* @var array
*/
public $bindings = [
ServerProvider::class => DigitalOceanServerProvider::class,
];
 
/**
* Todos los singletons de contenedor que deben registrarse.
*
* @var array
*/
public $singletons = [
DowntimeNotifier::class => PingdomDowntimeNotifier::class,
ServerProvider::class => ServerToolsProvider::class,
];
}

El Método Boot

Entonces, ¿qué pasa si necesitamos registrar un compositor de vistas dentro de nuestro proveedor de servicios? Esto debe hacerse dentro del método boot. Este método se llama después de que todos los demás proveedores de servicios hayan sido registrados, lo que significa que tienes acceso a todos los demás servicios que han sido registrados por el framework:

<?php
 
namespace App\Providers;
 
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
 
class ComposerServiceProvider extends ServiceProvider
{
/**
* Inicializa cualquier servicio de la aplicación.
*/
public function boot(): void
{
View::composer('view', function () {
// ...
});
}
}

Inyección de Dependencias en el Método Boot

Puedes indicar las dependencias del método boot de tu proveedor de servicios mediante el tipo de declaración. El contenedor de servicios inyectará automáticamente todas las dependencias que necesites:

use Illuminate\Contracts\Routing\ResponseFactory;
 
/**
* Inicializa cualquier servicio de la aplicación.
*/
public function boot(ResponseFactory $response): void
{
$response->macro('serialized', function (mixed $value) {
// ...
});
}

Registro de Proveedores

Todos los proveedores de servicios se registran en el archivo de configuración config/app.php. Este archivo contiene una matriz providers donde puedes listar los nombres de clase de tus proveedores de servicios. Por defecto, se registran en esta matriz un conjunto de proveedores de servicios principales de Laravel. Los proveedores predeterminados inicializan los componentes principales de Laravel, como el envío de correos, la cola, la caché y otros.

Para registrar tu proveedor, agrégalo a la matriz:

'providers' => ServiceProvider::defaultProviders()->merge([
// Otros Proveedores de Servicios
 
App\Providers\ComposerServiceProvider::class,
])->toArray(),

Proveedores Diferidos

Si tu proveedor solo registra enlaces en el contenedor de servicios, puedes optar por diferir su registro hasta que realmente se necesite uno de los enlaces registrados. Retrasar la carga de dicho proveedor mejorará el rendimiento de tu aplicación, ya que no se carga desde el sistema de archivos en cada solicitud.

Laravel compila y almacena una lista de todos los servicios suministrados por proveedores de servicios diferidos, junto con el nombre de su clase de proveedor de servicios. Entonces, solo cuando intentas resolver uno de estos servicios, Laravel carga el proveedor de servicios.

Para diferir la carga de un proveedor, implementa la interfaz \Illuminate\Contracts\Support\DeferrableProvider y define un método provides. El método provides debería devolver los enlaces del contenedor de servicios registrados por el proveedor:

<?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 cualquier servicio de la aplicación.
*/
public function register(): void
{
$this->app->singleton(Connection::class, function (Application $app) {
return new Connection($app['config']['riak']);
});
}
 
/**
* Obtiene los servicios proporcionados por el proveedor.
*
* @return array<int, string>
*/
public function provides(): array
{
return [Connection::class];
}
}