Proveedores De Servicio

Proveedores de servicio

Introducción

Los proveedores de servicios son el lugar central de toda la inicialización de aplicaciones de Laravel. Tu propia aplicación, así como todos los servicios centrales de Laravel, se inicializan a través de proveedores de servicios.

Pero, ¿qué queremos decir con “inicializar”? En general, nos referimos a registrar cosas, incluyendo el registro de enlaces del contenedor de servicios, oyentes de eventos, middleware e incluso rutas. Los proveedores de servicios son el lugar central para configurar tu aplicación.

Laravel utiliza docenas de proveedores de servicios internamente para inicializar sus servicios centrales, como el sistema de correos, la cola, el caché y otros. Muchos de estos proveedores son proveedores “diferidos”, lo que significa que no se cargarán en cada solicitud, sino solo cuando los servicios que proporcionan sean realmente necesarios.

Todos los proveedores de servicios definidos por el usuario están registrados en el archivo bootstrap/providers.php. En la siguiente documentación, aprenderás cómo escribir tus propios proveedores de servicios y registrarlos en tu aplicación de Laravel.

Writting Service Provideres

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 al contenedor de servicios. Nunca debes intentar registrar oyentes de eventos, rutas o cualquier otra funcionalidad dentro del método register.

La interfaz de línea de comandos Artisan puede generar un nuevo proveedor a través del comando make

. Laravel registrará automáticamente tu nuevo proveedor en el archivo bootstrap/providers.php de tu aplicación:

php artisan make:provider RiakServiceProvider

El Método Register

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

Echemos un vistazo a 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
{
    /**
     * Register any application services.
     */
    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 muchas vinculaciones simples, es posible que desees utilizar las propiedades bindings y singletons en lugar de registrar manualmente cada vinculación del contenedor. Cuando el framework carga el proveedor de servicios, automáticamente revisará estas propiedades y registrará sus vinculaciones:

<?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
{
    /**
     * All of the container bindings that should be registered.
     *
     * @var array
     */
    public $bindings = [
        ServerProvider::class => DigitalOceanServerProvider::class,
    ];
 
    /**
     * All of the container singletons that should be registered.
     *
     * @var array
     */
    public $singletons = [
        DowntimeNotifier::class => PingdomDowntimeNotifier::class,
        ServerProvider::class => ServerToolsProvider::class,
    ];
}

The boot method

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
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        View::composer('view', function () {
            // ...
        });
    }
}

Boot Method Dependency Injection

Puedes sugerir las dependencias en el método boot, el contenedor de servicios inyectará las dependencias.

use Illuminate\Contracts\Routing\ResponseFactory;
 
/**
 * Bootstrap any application services.
 */
public function boot(ResponseFactory $response): void
{
    $response->macro('serialized', function (mixed $value) {
        // ...
    });
}

Todos los proveedores de servicios están registrados en el archivo de configuración bootstrap/providers.php. Este archivo devuelve un array que contiene los nombres de clase de los proveedores de servicios de tu aplicación:

<?php
return [
    App\Providers\AppServiceProvider::class,
];

Cuando invocas el comando make de Artisan, Laravel agregará automáticamente el proveedor generado al archivo bootstrap/providers.php. Sin embargo, si has creado manualmente la clase del proveedor, debes agregar manualmente la clase del proveedor al array:

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

Deferred Providers

Si tu proveedor solo está registrando vinculaciones en el contenedor de servicios, puedes optar por diferir su registro hasta que una de las vinculaciones registradas sea realmente necesaria. Diferir 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 proporcionados por los proveedores de servicios diferidos, junto con el nombre de su clase de proveedor de servicios. Luego, 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 debe devolver las vinculaciones del contenedor de servicios registradas 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
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->singleton(Connection::class, function (Application $app) {
            return new Connection($app['config']['riak']);
        });
    }
 
    /**
     * Get the services provided by the provider.
     *
     * @return array<int, string>
     */
    public function provides(): array
    {
        return [Connection::class];
    }
}