Skip to main content

How to build a basic service with dependency injection for Drupal 8

Updated by Tim Rabbetts on
artificial intelligence, brain, think

In this article, we are going to see how we could create a simple Drupal 8 service, and then we are going to inject some stuff into it in order to see how Dependency Injection works.  This process relates to PSR-11 https://www.php-fig.org/psr/psr-11/

The easiest way to build a module, create a service, build controller, pretty much anything in Drupal 8 is with the amazing drupal console.  Run these commands to generate a service, remember to then enable the module.  

drupal generate:module
drupal generate:service
drupal generate:controller

Let's see first how we declare a service class inside of our Drupal 8 module. It's a normal PHP class that is located under the /src folder in the module.

<?php

namespace Drupal\demo_service;

/**
 * Class DefaultService.
 */
class DefaultService {

  /**
   * Constructs a new DefaultService object.
   */
  public function __construct() {

  }

  public function hello() {
    ob_start();
    ?>
    <pre>
    _          _ _         _ _ _   _   _        _           _     _     _ _
   | |__   ___| | | ___   | (_) |_| |_| | ___  | |__   ___ | |__ | |__ (_) |_
   | '_ \ / _ \ | |/ _ \  | | | __| __| |/ _ \ | '_ \ / _ \| '_ \| '_ \| | __|
   | | | |  __/ | | (_) | | | | |_| |_| |  __/ | | | | (_) | |_) | |_) | | |_
   |_| |_|\___|_|_|\___/  |_|_|\__|\__|_|\___| |_| |_|\___/|_.__/|_.__/|_|\__|

    </pre>

   <?php
   return ob_get_clean();
  }
}

In addition to this, there is a module.services.yml file that tells drupal about our service.

services:
  demo_service.default:
    class: Drupal\demo_service\DefaultService
    arguments: []

I also created a controller so we can use the service and dump out its result to the browser.

<?php

namespace Drupal\demo_service\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Class DefaultController.
 */
class DefaultController extends ControllerBase {

  /**
   * Hello.
   *
   * @return string
   *   Return Hello string.
   */
  public function hello() {

    $service = \Drupal::service('demo_service.default');
    $markup = $service->hello();

    return [
      '#type' => 'markup',
      '#markup' => $markup
    ];
  }

}

These are the key bits of code, it's how you instantiate and run the custom service.

$service = \Drupal::service('demo_service.default');
$markup = $service->hello();

The output is shown below, quick and simple drupal service!

Demo drupal 8 service

Now for the really cool bit, let's inject a dependency and use it.  First, we need to change the module.services.yml to tell Drupal what we need, in this case its the current user object.

services:
  demo_service.default:
    class: Drupal\demo_service\DefaultService
    arguments: ['@current_user']

Then we change the service, the constructor gets the user and sets the private user value in our service.  We then call the getDisplayName to show the user's name.  Also, don't forget we need to have the use Drupal\Core\Session\AccountInterface; statement at the start.

<?php

namespace Drupal\demo_service;

use Drupal\Core\Session\AccountInterface;

/**
 * Class DefaultService.
 */
class DefaultService {

  private $currentUser;

  /**
   * Part of the DependencyInjection magic happening here.
   */
  public function __construct(AccountInterface $currentUser) {
    $this->currentUser = $currentUser;
  }

  public function hello() {
    ob_start();
    ?>
    <pre>
    _          _ _
   | |__   ___| | | ___
   | '_ \ / _ \ | |/ _ \
   | | | |  __/ | | (_) |
   |_| |_|\___|_|_|\___/

    </pre>
    <?php
   return ob_get_clean() . $this->currentUser->getDisplayName();
  }
}

Now we clear the cache and hey presto the dependency inject has worked!!  That's a very simple example of dependency injection and custom service creation within Drupal 8.

demo service hello

Add new comment