Servicios en Drupal 8: Como utilizarlos

Imagen

En anteriores artículos hemos hablado sobre los servicios en Drupal 8 y hemos visto como podíamos crear uno simple, ahora veremos como podemos usarlos en diferentes situaciones, tales como funciones dentro de modulo.module, plugins o controladores.

En el archivo modulo.module:

Esto es lo mas sencillo de hacer, tenemos que utilizar la clase estática Drupal y utilizar el método "service" para obtener el servicio que queramos:

/**
 * Implements hook_cron().
 */
function nireneko_cron() {
  //Obtenemos el servicio utilizando la clase estatica Drupal.
  $neko_tools = \Drupal::service('nireneko.tools');
  //Utilizarmos el servicio.
  $neko_tools->repetir();
}

Con esto, ya podemos obtener y utilizar el servicio que queramos, en el ejemplo hemos obtenido el llamado 'nireneko.tools' y llamado al método repetir que tiene.

 

En controladores:

Utilizar los servicios en los controladores de manera correcta, cuesta un poco mas, ya que cuando se conoce el uso de la clase estática Drupal, lo mas fácil y rápido, es usarla. Pero esto no es lo correcto, ya que la clase Drupal unicamente debería de usarse fuera de objetos, dentro de estos se debe de usar la inyección de dependencias, que es lo que vamos a ver a continuación.

Lo primero, que tenemos que hacer, es crear el metódo estático "create", el cual nos permite utilizar el contenedor para obtener los servicios que queramos:

/**
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *
   * @return \Drupal\Core\Controller\ControllerBase|\NekoController
   */
  static function create(ContainerInterface $container){
    //En el metodo estatico create, tenemos que obtener los servicios que queramos para
    //para luego a traves del constructor meterlo en el atributo privado.
    return new static(
      $container->get('nireneko.tools')
    );
  }

Ahora, tenemos que modificar el constructor de la clase, para poder inicializar el atributo de la clase correspondiente al servicio.

/**
   * @var \Drupal\nireneko\Services\NirenekoTools
   */
  private $neko_tools;

  /**
   * NekoController constructor.
   *
   * @param \Drupal\nireneko\Services\NirenekoTools $neko_tools
   */
  public function __construct(NirenekoTools $neko_tools) {
    //Inicializamos el atributo $neko_tools con el servicio obtenido del metodo estatico create
   $this->neko_tools = $neko_tools;
  }

Y listo, ahora ya podremos utilizar el servicio en todos los métodos de la clase:

/**
   * Accion a la que se llama en el controlador
   */
  public function nekoAction() {
    //Utilizando el servicio que hemos obtenido.
    $this->neko_tools->repetir();
  }

En plugins:

Realizar la inyeccion de dependencias en los plugins, es exactamente lo mismo que en un controlador, pero la diferencia esta, en que tenemos que implementar la clase llamada ContainerFactoryPluginInterface o Drupal no llamada al método estático create.

class NekoBlock extends BlockBase implements ContainerFactoryPluginInterface {

Y listo, el resto es exactamente lo mismo que en un controlador.

Servicios dentro de servicios:

En este caso, varia un poco el como injectar servicios dentro de otros, lo que tenemos que hacer, es editar el archivo modulo.services.yml y añadir como argumento el servicio que queramos y este se nos pasara al constructor:

services:
  nireneko.tools:
    class: Drupal\nireneko\Services\NirenekoTools
    arguments: ['@messenger']

Ahora modificar el constructor para poder obtener el servicio messenger:

/**
   * NirenekoTools constructor.
   *
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   */
  public function __construct(MessengerInterface $messenger) {
    $this->messenger = $messenger;
  }
 

Conclusión:

Con esto ya hemos visto como utilizar los servicios en distintos tipos de clases, esto es la inyección de dependencias y aunque suene extraño, es muy sencillo como se puede ver.

Estructura de archivos para el uso de servicios

Como siempre, tenéis un archivo con el código de ejemplo para que lo podáis ver con comodidad por si algo no ha quedado claro, y también los comentarios para aclarar cualquier duda.

Artículos relacionados: