back

Knowledge Centre

Erstellung von benutzerdefinierten Diensten in Drupal 8: Ein umfassender Leitfaden

| 20.11.2018

Erstellen von benutzerdefinierten Diensten in Drupal 8: Ein umfassender Leitfaden

Die Dependency-Injection ist ein grundlegendes Entwurfsmuster in Drupal 8, das die Wiederverwendbarkeit und Wartbarkeit von Code fördert. Durch die Entkopplung von Funktionen können wir effizienteren Code schreiben, der einfacher zu testen und zu warten ist. Lassen Sie uns erforschen, wie man benutzerdefinierte Dienste mit Dependency-Injection implementiert.

Kerndienste in Drupal 8

Die Kerndienste von Drupal sind in der Datei `core.services.yml` definiert. Hier ist ein Beispiel, wie ein Kerndienst deklariert wird:

services:
 path.current:
   class: Drupal\Core\Path\CurrentPathStack
   arguments: ['@request_stack']

Diese Deklaration enthält drei Schlüsselelemente:
- Der Dienstname (`path.current`)
- Die implementierende Klasse
- Erforderliche Abhängigkeiten (als Argumente übergeben)

Um diesen Dienst in einem statischen Kontext zu verwenden:

// Hinweis: Statische Dienstaufrufe sollten möglichst vermieden werden
$currentPath = \Drupal::service('path.current');
$path = $currentPath->getPath();

Erstellung eines benutzerdefinierten Dienstes

Lassen Sie uns einen benutzerdefinierten Dienst in einem Modul namens "mymodule" erstellen. Erstellen Sie zuerst eine Datei namens `mymodule.services.yml` im Stammverzeichnis Ihres Moduls:

services:
 mymodule.tools:
   class: Drupal\mymodule\MyTools
   arguments: ['@database']

Nun implementieren wir die Dienstklasse (`MyTools.php`) im `src` Verzeichnis:

namespace Drupal\mymodule;
use Drupal\Core\Database\Connection;
/**
* Stellt Hilfsfunktionen für die Arbeit mit Knoten zur Verfügung.
*/
class MyTools {
 /**
  * Die Datenbankverbindung.
  *
  * @var \Drupal\Core\Database\Connection
  */
 protected $database;
 /**
  * Erstellt einen neuen MyTools-Dienst.
  *
  * @param \Drupal\Core\Database\Connection $connection
  *   Die Datenbankverbindung.
  */
 public function __construct(Connection $connection) {
   $this->database = $connection;
 }
 /**
  * Ruft die Autor-ID eines Knotens ab.
  *
  * @param int $nid
  *   Die Knoten-ID.
  *
  * @return int|null
  *   Die Benutzer-ID des Knotenautors oder null, wenn nicht gefunden.
  */
 public function showAuthor($nid) {
   $query = $this->database->select('node_field_data', 'nfd')
     ->fields('nfd', ['uid'])
     ->condition('nfd.nid', $nid);
   
   $result = $query->execute()->fetchAll();
   
   return !empty($result) ? $result[0]->uid : NULL;
 }
}

Zugriff auf benutzerdefinierte Dienste

Es gibt zwei Hauptwege, um auf Dienste zuzugreifen:

1. Statischer Service-Container (nicht empfohlen)

// Vermeiden Sie diesen Ansatz in objektorientiertem Code
$toolService = \Drupal::service('mymodule.tools');
$authorId = $toolService->showAuthor(15);

 2. Dependency Injection (empfohlen)

/**
* Demonstriert die korrekte Dienstinjektion.
*/
class MyController extends ControllerBase {
 /**
  * Der benutzerdefinierte Tools-Dienst.
  *
  * @var \Drupal\mymodule\MyTools
  */
 protected $myTools;
 /**
  * Erstellt einen neuen MyController.
  *
  * @param \Drupal\mymodule\MyTools $my_tools
  *   Der benutzerdefinierte Tools-Dienst.
  */
 public function __construct(MyTools $my_tools) {
   $this->myTools = $my_tools;
 }
 /**
  * {@inheritdoc}
  */
 public static function create(ContainerInterface $container) {
   return new static(
     $container->get('mymodule.tools')
   );
 }
 /**
  * Beispiel-Methode, die den Dienst verwendet.
  */
 public function exampleMethod($nid) {
   $authorId = $this->myTools->showAuthor($nid);
   // Verarbeiten Sie $authorId wie benötigt
 }
}

Best Practices

1. Verwenden Sie immer Dependency Injection in Klassen anstatt statische Dienstaufrufe
2. Benennen Sie Dienste konsistent, beginnend mit dem Namen Ihres Moduls
3. Dokumentieren Sie Ihre Dienstklassen und -methoden gründlich
4. Fügen Sie korrekte Typ-Hinweise und Rückgabetyp-Deklarationen hinzu
5. Behandeln Sie Fehlerfälle und geben Sie geeignete Standardwerte zurück

Indem Sie diese Muster befolgen, erstellen Sie wartbareren und testbareren Code, der gut mit der Service-Container-Architektur von Drupal integriert ist.

Drupal 8
  • Wissen
    Wissenszentrum
    Im Gehirn einer KI
  • Wissen
    Wissenszentrum
    Feinabstimmung von LLaMA zur Nachbildung von Eminescus literarischem Stil
  • Wissen
    Wissenszentrum
    Ein neues Zeitalter beginnt: Drupal CMS 1.0 startet