
Crearea Serviciilor Personalizate în Drupal 8: Un Ghid Complet
Injectarea dependențelor este un model fundamental de design în Drupal 8 care promovează reutilizarea și întreținerea codului. Prin decuplarea funcționalității, putem scrie un cod mai eficient, care este mai ușor de testat și întreținut. Să explorăm cum să implementăm servicii personalizate folosind injectarea dependențelor.
Serviciile de bază în Drupal 8
Serviciile de bază ale Drupal sunt definite în fișierul `core.services.yml`. Iată un exemplu de cum este declarat un serviciu de bază:
services:
path.current:
class: Drupal\Core\Path\CurrentPathStack
arguments: ['@request_stack']
Această declarație include trei elemente cheie:
- Numele serviciului (`path.current`)
- Clasa care îl implementează
- Dependințele necesare (transmise ca argumente)
Pentru a utiliza acest serviciu într-un context static:
// Notă: Apelurile de serviciu statice ar trebui evitate când este posibil
$currentPath = \Drupal::service('path.current');
$path = $currentPath->getPath();
Crearea unui serviciu personalizat
Să creăm un serviciu personalizat într-un modul numit "mymodule". Mai întâi, creați un fișier numit `mymodule.services.yml` în directorul rădăcină al modulului:
services:
mymodule.tools:
class: Drupal\mymodule\MyTools
arguments: ['@database']
Acum, să implementăm clasa de serviciu (`MyTools.php`) în directorul `src`:
namespace Drupal\mymodule;
use Drupal\Core\Database\Connection;
/**
* Provides utility functions for working with nodes.
*/
class MyTools {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* Constructs a new MyTools service.
*
* @param \Drupal\Core\Database\Connection $connection
* The database connection.
*/
public function __construct(Connection $connection) {
$this->database = $connection;
}
/**
* Retrieves the author ID of a node.
*
* @param int $nid
* The node ID.
*
* @return int|null
* The user ID of the node author, or null if not found.
*/
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;
}
}
Accesarea serviciilor personalizate
Există două modalități principale de a accesa serviciile:
1. Container de servicii statice (Nu este recomandat)
// Evitați această abordare în codul orientat pe obiecte
$toolService = \Drupal::service('mymodule.tools');
$authorId = $toolService->showAuthor(15);
2. Injectarea dependențelor (Recomandat)
/**
* Demonstrates proper service injection.
*/
class MyController extends ControllerBase {
/**
* The custom tools service.
*
* @var \Drupal\mymodule\MyTools
*/
protected $myTools;
/**
* Constructs a new MyController.
*
* @param \Drupal\mymodule\MyTools $my_tools
* The custom tools service.
*/
public function __construct(MyTools $my_tools) {
$this->myTools = $my_tools;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('mymodule.tools')
);
}
/**
* Example method using the service.
*/
public function exampleMethod($nid) {
$authorId = $this->myTools->showAuthor($nid);
// Procesați $authorId după cum este necesar
}
}
Practici de bună conduită
1. Utilizați întotdeauna injectarea dependențelor în clase, în locul apelurilor de servicii statice
2. Numește serviciile în mod consecvent, începând cu numele modulului tău
3. Documentează în mod complet clasele și metodele de serviciu
4. Include indicii de tip corecte și declarații de tip de returnare
5. Gestionează cazurile de eroare și returnează valori implicite adecvate
Urmărind aceste modele, veți crea un cod mai întreținut și testabil care se integrează bine cu arhitectura containerului de servicii Drupal.
