Drupal 8: Inyección de servicios

Cabecera - Drupal 8: Inyección de servicios

Drupal 8: Inyección de servicios

  • Autor: fjavimartin

  • Fecha de Creación: 22/01/2018

  • Categorías:

    • Drupal,
    • Drupal 8,
    • Php,
    • Simfony,
    • Inyección de servicios

Una novedad de Drupal8 es la inyección de servicios, en este artículo explicaremos en que consiste y como utilizarla.

Drupal dispone de un contenedor de servicios que añaden funcionalidades reutilizables en todo el sistema. El core de Drupal aporta multitud de funciones básicas como son la del acceso al usuario actual o entidades del sistema, pero lo bueno de esto es que cualquier módulo contribuido puede aportar sus propios servicios.

Podéis encontrar el listado completo de servicios en la siguiente url: https://api.drupal.org/api/drupal/core%21core.services.yml/8.2.x.

Por ejemplo, podremos acceder al usuario actual del sistema con el siguiente código:

$user = \Drupal::currentUser();

o también:

$user = \Drupal::service(‘current_user’);

En lugar de acceder directamente a los diferentes servicios tal y como hemos visto en el anterior ejemplo, lo que haremos será inyectar el servicio en la clase deseada de la siguiente forma:

<?php

namespace Drupal\equipos_services\Form;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;

class ExampleForm extends FormBase {
  protected $current_user;
  
  public function __construct(AccountProxyInterface $current_user) {
    $this->current_user = $current_user;
  }
  
  public static function create(ContainerInterface $container) {
    return new static (
      $container->get('current_user')
    );
  }
  
  public function getFormId() {
    return 'ExampleForm';
  }
  
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['test'] = [
      '#type' => 'textfield',
      '#title' => 'Test',
      '#description' => 'Description textfield',
      '#default' => $this->current_user->id(),
    ];
  }
  
  public function submitForm(array &$form, FormStateInterface $form_state) { }
}

En este formulario de ejemplo hemos inyectado el servicio ‘current_user’. Seguiremos los siguientes pasos:

  • Declararemos en nuestra clase una variable que recogerá el objeto del que finalmente utilizaremos sus métodos.
  • Necesitaremos incluir la función __construct() que recibirá como argumentos la interface que implementa la clase recoge la lógica del servicio. Podremos incluir tantos argumentos como servicios vayamos a necesitar.
  • Por último necesitaremos añadir la función create() que recibe como parámetro la interface del contenedor de servicios de la que obtendremos los diferentes servicios que necesitaremos.

Cuando queramos localizar un servicio cualquier en drupal bastará con ir al fichero core.services.yml donde están recogidos todos los servicios que incluye el core y localizaremos la interface que implemente la clase.

Por ejemplo, para añadir el servicio que nos dará acceso a las entidades del sistema (entity_type.manager) nos iremos al fichero indicado anteriormente (core.services.yml) y localizamos la clase del servicio:

entity_type.manager: 
  class: Drupal\Core\Entity\EntityTypeManager 
  arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', @string_translation', '@class_resolver'] 
  parent: container.trait 
  tags: 
    - { name: plugin_manager_cache_clear }

Localizamos la clase del servicio y vemos que interface implementa:

class EntityTypeManager extends DefaultPluginManager implements EntityTypeManagerInterface, ContainerAwareInterface {

Esta clase implementa dos interfaces...¿Cuál será la que tengamos que utilizar en nuestra función __construct()? Fácil, solamente tendremos que acceder a las diferentes interfaces para ver la que tiene los métodos que nos interesa → EntityTypeManagerInterface.

La manera de inyectar este servicio será:

protected $entityManagerInterface;
  
  public function __construct(EntityTypeManagerInterface $entityManagerInterface) {
    $this->entityManagerInterface = $entityManagerInterface;
  }
  
  public function create(ContainerInterface $container) {
    return new static (
      $container->get('entity_type.manager')
    );
  }

Disfrutar!!!!!

Referencias

https://api.drupal.org/api/drupal/core%21core.services.yml/8.2.x

https://api.drupal.org/api/drupal/core%21core.services.yml/service/current_user/8.2.x

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Session%21AccountProxyInterface.php/interface/AccountProxyInterface/8.2.x

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityTypeManager.php/class/EntityTypeManager/8.2.x

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityTypeManagerInterface.php/interface/EntityTypeManagerInterface/8.2.x

Todos los Derechos Reservados © 2016

Funciona con Drupal