Overriding Drupal 8 services

Submitted by timmillwood on Mon, 27/07/2015 - 11:40

Since July 2014 there’s been a feature in Drupal 8 to override backend specific services. There are over 25 services in Drupal core that are backend overridable.


In this post we'll look at a simple way to override services using aliases, which comes downstream fro symfony.

A simple service is the “user.data” service. It allows data to be stored, fetched and deleted, relating to a user account. For this there is an interface, UserDataInterface and this is implemented by UserData. We need to create a module that adds a new service that implements UserDataInterface.

Firstly create a folder for your module, something like alternative_userdata, then the file alternative_userdata.info.yml, in there we can define the module’s info:

name: Alternative UserData type: module description: Adds alternative storage for user data. core: 8.x dependencies: - user

So we are setting the name of the module, the type, a description of it the core version and that it depends on the user module.

Next we need to define our service, for this you wil need to create the file alternative_userdata.services.yml. In here we can add the service called alternative_userdata.user.data and set the class.

services: alternative_userdata.user.data: class: Drupal\alternative_userdata\AlternativeUserData

Next is to create the class, add a folder named “src” (following PSR-4 autoloading standards) and within this a file called AlternativeUserData.php.

<?php /** * @file * Contains \Drupal\alternative_userdata\AlternativeUserData. */ namespace Drupal\alternative_userdata; // Here you may need to add the use operator to pull in any backend client. /** * Defines the alternative user data service. */ class AlternativeUserData implements UserDataInterface { // You may need to add a protected variable here for your backend client. /** * Constructs a new user data service. */ public function __construct() { // Here you can create a new instance of your backend client. } /** * Implements \Drupal\user\UserDataInterface::get(). */ public function get($module, $uid = NULL, $name = NULL) { // This needs to return the user data from your backend. } /** * Implements \Drupal\user\UserDataInterface::set(). */ public function set($module, $uid, $name, $value) { // This needs to save the user data to your backend. } /** * Implements \Drupal\user\UserDataInterface::delete(). */ public function delete($module = NULL, $uid = NULL, $name = NULL) { // This needs to save your user data to your backend. } }

Now that we have a service defined in our module, the module can be enabled, however it won’t do anything until we set an alias in your site’s services.yml file.

Edit services.yml (normally at sites/default/services.yml in your Drupal 8 codebase) and add the following:

services: user.data: alias: alternative_userdata.user.data

Now when Drupal looks to use the user.data service it will actually use the alternative_userdata.user.data service from your module.

Simple, right?

Edit: Lee Rowlands expands on this in his post Overriding services in Drupal 8 - advanced cases.

Add new comment