10

I'm new to services (and drupal 8!) and trying to figure out services. I think perhaps I'm just doing the create in an outdated way. What I want do is make my 'hello generator' a service and call it in another controller with the following:

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'
  • You can follow document. It's correct way to call a service in a controller – MrD Aug 5 '16 at 17:46
22

There are 3 questions here:

  1. How to create a controller?
  2. How to create a service?
  3. How to use services in a controller?

1. Create a controller

1.1 Add a controller class - you did it. For others see Drupal documentation

1.2 Add a routing file - it looks like this is missing in your code:

my_module.routing.yml

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

see Drupal documentation

2. Create a service

2.1 Add a service class - you did it.

2.2 Add a routing file - you did it although it contains extra code that belongs to the routing file. This is all you need:

my_module.services.yml

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

see Drupal documentation

3. Use services in a controller

You did it. Here's a reference for others:

3.1 Override the create() method

The controller class inherits this method from class ControllerBase. Its role is to create the controller object. Watch the method argument: it is passed the services container. Extract the services you need and pass them to the constructor:

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 Initialise services in __construct()

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

3.3 Start using the services

| improve this answer | |
  • 4
    I wish the official documentation was more in this style, or at least had a few overview articles that was. Short and concise with a generic example easily translated to the real application. – Nicolaj Feb 1 '18 at 9:59
  • A do not forget: use Symfony\Component\DependencyInjection\ContainerInterface; in controller class – Atep Feb 27 at 8:02
  • While I totally agree with @Nicolaj's comment, this isn't working for me...and I'm not even trying to use a custom service! All I want to do is create a class member variable that holds a static database connection object. I'm used to using systems where connection pooling and never creating more connections than you need is the norm. So how would I implement something similar in a Drupal controller/form? – Kenny83 Apr 8 at 15:11
  • You might want to open another question @Kenny83, but have you looked at api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/… ? With that you can do something like this: gist.github.com/glaux/f4f1517563ddb57fb98b9213802c1569 – Nicolaj Apr 8 at 15:22
  • @Nicolaj LOL thanks for pointing out the bleedingly-obvious mate :P I'm well-aware of the core database service and that's what I'm trying to return from my create() method. I suppose you wouldn't have said that though if I hadn't missed something else that should have been obvious...I guess that service does pool connection objects? – Kenny83 Apr 8 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.