Skip to main content

Drupal 8^: How to inject a Service into a Class (Controller, Form, Plugin Block, etc) and why not into another service Class

In general it is a good practice to inject a service whenever is possible. For me, one of the most common services that i have to inject in another service is the Guzzle httpClient Service. You have an API that you want to use and CRUD some data and then you have your own Drupal Service Class that you want to call in a Controller or in a custom block etc. Of course you can call the httpClient or any other service procedular like this

$client = \Drupal::httpClient();
$request = $client->get('https://github.com/codeafrica/github-africa');
$response = $request->getBody();

but this is drupal 8^.  Dependency Injection is the way to go for so many reasons.

So let's get started:

Inject into a Class (Controller, Form, Plugin Block, etc)

 /**
   * Guzzle Http Client.
   *
   * @var GuzzleHttp\Client
   */
  protected $httpClient;

 /**
   * Constructs a new Class.
   *
   * @param \GuzzleHttp\Client $http_client
   *   The http_client.
   */
  public function __construct(
    Client $http_client
  ) {
    $this->httpClient = $http_client;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('http_client')
    );
  }

Inject a service into a service Class

In your custom services yml file you "inject" the service as an argument. If you want to know how i know that @http_client is the correct name of the service keep reading.

// modules/custom/example/example.services.yml
services:
  example.default:
    class: Drupal\example\DefaultService
    arguments: ["@http_client"]

After that we inject it in our service Class like this

// modules/custom/example/src/DefaultService.php
 /**
   * GuzzleHttp\Client definition.
   *
   * @var GuzzleHttp\Client
   */
  protected $http_client;
  /**
   * Constructor.
   */
  public function __construct(Client $http_client) {
    $this->http_client = $http_client;
  }

Important do not forget to add:

use GuzzleHttp\Client;

after the namespace of your Class (service, block, controller etc)

Tip: You can find the name of the httpClient service by using drupal console and in the terminal type this:

 drupal container:debug | grep 'http'

which gave me this output

 http_client                                                                 GuzzleHttp\Client                                                         
 http_client_factory                                                         Drupal\Core\Http\ClientFactory                                            
 http_kernel                                                                 Stack\StackedHttpKernel                                                   
 http_kernel.basic                                                           Symfony\Component\HttpKernel\HttpKernel  

So this how i knew to pass the http_client argument in the services yml file.

 

From: https://gist.github.com/jmolivas/ca258d7f2742d9e1aae4#inject-into-a-cla…

php service