Richtige Methode zum Aufrufen eines Dienstes in einer Steuerung

10

Ich bin neu in Diensten (und Drupal 8!) Und versuche, Dienste herauszufinden. Ich denke, vielleicht mache ich das Erstellen nur auf veraltete Weise. Was ich tun möchte, ist, meinen "Hallo-Generator" zu einem Dienst zu machen und ihn in einem anderen Controller mit den folgenden Eigenschaften aufzurufen:

DBController.php

namespace Drupal\db\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\db\DbServices\HelloGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;


class DBController extends ControllerBase
{
private $helloGenerator;

public function __construct(HelloGenerator $x) {
    $this->helloGenerator = $x;
}
public function say($count) {
    $hello = $this->helloGenerator->getHello($count);

    return new Response($hello);
}

public static function create(ContainerInterface $container) {
    $x = $container->get('db.hello_generator');
    return new static ($x);
}
}

HellGenerator.php

Namespace Drupal \ db \ DbServices;

class HelloGenerator {

public function getHello($count) {
    $foo = 4 + 4 + 4;
    return $foo . ' ' . $count;
}

}

db.services.yml

services:
  db.hello_generator:
     class: Drupal\db\DbServices\HelloGenerator

db.db_says:
  path: /db/says/{count}
  defaults:
    _controller: '\Drupal\db\Controller\DBController::say'
  requirements:
    _permission: 'access content'
karl
quelle
Sie können dem Dokument folgen . Es ist der richtige Weg, einen Dienst in einem Controller
anzurufen

Antworten:

21

Hier gibt es 3 Fragen:

  1. Wie erstelle ich einen Controller?
  2. Wie erstelle ich einen Service?
  3. Wie verwende ich Dienste in einem Controller?

1. Erstellen Sie einen Controller

1.1 Fügen Sie eine Controller-Klasse hinzu - Sie haben es geschafft. Für andere siehe Drupal-Dokumentation

1.2 Fügen Sie eine Routing-Datei hinzu - es scheint, dass dies in Ihrem Code fehlt:

my_module.routing.yml

my_module.my_route_name:
  path: '/my/path'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::myAction'
  requirements:
    _permission: 'access content'

Siehe Drupal-Dokumentation

2. Erstellen Sie einen Service

2.1 Fügen Sie eine Serviceklasse hinzu - Sie haben es geschafft.

2.2 Hinzufügen einer Routing-Datei - Sie haben es getan, obwohl sie zusätzlichen Code enthält, der zur Routing-Datei gehört. Das ist alles was Sie brauchen:

my_module.services.yml

services:
  my_module.my_service:
    class: Drupal\my_module\Service\MyService

Siehe Drupal-Dokumentation

3. Verwenden Sie Dienste in einem Controller

Du hast es geschafft. Hier ist eine Referenz für andere:

3.1 Überschreiben Sie die create()Methode

Die Controller-Klasse erbt diese Methode von class ControllerBase. Seine Aufgabe besteht darin, das Controller-Objekt zu erstellen. Beobachten Sie das Methodenargument: Es wird der Service-Container übergeben. Extrahieren Sie die benötigten Services und übergeben Sie sie an den Konstruktor:

public static function create(ContainerInterface $container) {
    $my_service = $container->get('my_module.my_service');
    $other_service = $container->get('other_service');

    return new static($my_service, $other_service);
}

3.2 Dienste in initialisieren __construct()

public function __construct($my_service, $other_service)
{
    $this->my_service = $my_service;
    $this->other_service = $other_service;
}

3.3 Starten Sie die Dienste

Zendka
quelle
3
Ich wünschte, die offizielle Dokumentation wäre mehr in diesem Stil oder hätte zumindest ein paar Übersichtsartikel. Kurz und prägnant mit einem allgemeinen Beispiel, das leicht in die reale Anwendung übersetzt werden kann.
Nicolaj
A nicht vergessen: Verwenden Sie Symfony \ Component \ DependencyInjection \ ContainerInterface. in der Controller-Klasse
Atep
Obwohl ich dem Kommentar von @ Nicolaj voll und ganz zustimme, funktioniert dies bei mir nicht ... und ich versuche nicht einmal, einen benutzerdefinierten Service zu verwenden! Ich möchte lediglich eine Klassenmitgliedsvariable erstellen, die ein statisches Datenbankverbindungsobjekt enthält. Ich bin es gewohnt, Systeme zu verwenden, in denen Verbindungspooling und nie mehr Verbindungen als nötig erstellt werden. Wie würde ich etwas Ähnliches in einem Drupal-Controller / Formular implementieren?
Kenny83
Sie möchten vielleicht eine andere Frage bei Kenny83 öffnen, haben sich aber api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/… angesehen ? Damit können Sie so etwas tun: gist.github.com/glaux/f4f1517563ddb57fb98b9213802c1569
Nicolaj
@Nicolaj LOL, danke, dass Sie auf den blutig offensichtlichen Partner hingewiesen haben: P Ich kenne den zentralen Datenbankdienst sehr gut und versuche, von meiner create()Methode zurückzukehren. Ich nehme an würden Sie nicht gesagt haben , dass , obwohl , wenn ich etwas nicht verpasst hatte anderes , das sollte klar gewesen sein ... Ich denke , dass der Service funktioniert Pool Verbindungsobjekte?
Kenny83