Service Providers

Introducción

Los proveedores de servicios son el centro de toda la configuración de arranque de Laravel. Tu propia aplicación, al igual que todos los servicios del núcleo de Laravel, también tiene su configuración de arranque mediante proveedores de servicios.

Pero, ¿qué se entiende por "configuración de arranque"? In general, we mean registering things, including registering service container bindings, event listeners, middleware, and even routes. Los proveedores de servicios son el centro de la configuración de tu aplicación.

Si abres el archivo config/app.php incluído en Laravel, verás un array providers. Estas son todas las clases de los proveedores de servicios que serán cargadas en tu aplicación. Por supuesto, muchos de ellos son proveedores "diferidos", lo que significa que no van a ser cargados en cada petición sino que únicamente se cargarán cuando los servicios que proporcionan son solicitados.

En este resumen aprenderás a escribir tu propio proveedor de servicios y como registrarlo en tu aplicación Laravel.

Writing Service Providers

Todos los proveedores de servicios extienden de la clase Illuminate\Support\ServiceProvider. Esta clase abstracta requiere que al menos definas el método register en tu proveedor. Within the register method, you should only bind things into the service container. No deberías intentar registrar cosas tales como detectores de eventos, rutas o cualquier otra funcionalidad dentro del método register.

Desde la línea de comandos, Artisan puede generar fácilmente un nuevo proveedor de servicios gracias al comando make:provider:

php artisan make:provider RiakServiceProvider

El método Register

As mentioned previously, within the register method, you should only bind things into the service container. No deberías intentar registrar cosas tales como detectores de eventos, rutas o cualquier otra funcionalidad dentro del método register. Otherwise, you may accidently use a service that is provided by a service provider which has not loaded yet.

Ahora, vamos a ver un ejemplo básico de un proveedor de servicios:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('Riak\Contracts\Connection', function ($app) {
            return new Connection(config('riak'));
        });
    }
}

Este proveedor de servicio únicamente define el método register, y lo utiliza para definir una implementación de Riak\Contracts\Connection en el service container. If you don't understand how the service container works, check out its documentation.

El método Boot

So, what if we need to register a view composer within our service provider? Esto debería hacerse dentro del método boot. This method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('view', function () {
            //
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Boot Method Dependency Injection

We are able to type-hint dependencies for our boot method. The service container will automatically inject any dependencies you need:

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $factory)
{
    $factory->macro('caps', function ($value) {
        //
    });
}

Registrar proveedores

Todos los proveedores están registrados en el archivo de configuración config/app.php. Este archivo contiene un array de proveedores del cual puedes obtener un listado de nombres de tus proveedores de servicios. Por defecto, este array también incluye un conjunto de proveedores de servicios del núcleo de Laravel. Estos proveedores inicializan los componentes del núcleo de Laravel, tales como el proveedor de correos, colas, caché y otros.

Para registrar tu proveedor, simplemente añádelo al array:

'providers' => [
    // Otros proveedores de servicios

    'App\Providers\AppServiceProvider',
],

Proveedores diferidos

If your provider is only registering bindings in the service container, you may choose to defer its registration until one of the registered bindings is actually needed. Aplazar la carga de un proveedor de este tipo mejorará el rendimiento de tu aplicación, ya que no se cargará desde el sistema de ficheros para cada petición.

Para aplazar la carga de un proveedor, hay que configurar la propiedad defer a true y definir un método provides. El método provides retorna los bindings al service container que el provider registra:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**Registra el proveedor de servicios.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('Riak\Contracts\Connection', function ($app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ['Riak\Contracts\Connection'];
    }

}

Laravel compila y almacena una lista de todos los servicios ofrecidos por proveedores de servicios diferidos, junto al nombre de su clase proveedora del servicio. Entonces, sólo cuando se intenta resolver alguno de estos servicios, Laravel carga el proveedor de servicio.