There are many services available in Drupal 8 by default, but sometimes we need to write our own function/logic and the functionality should be available throughout the Drupal 8 application. This can be achieved by creating a custom Service in Drupal 8.
In this tutorial, I am going to show you how to create a Custom Service and how to use the Service by Injecting them into a Controller. And to create a custom Service, we need to create a Custom Module first.
If you don’t know how to create a Custom Module please visit here:
https://theonlytutorials.com/lets-create-a-simple-custom-module-in-drupal-8/
Okay, Let’s start by creating a folder called “my_module” and adding the my_module.info.yml file.
my_module.info.yml
name: My Module description: A custom module to create a Drupal Service type: module core_version_requirement: ^8 || ^9
If you don’t know already, here is a tip for you, the above file is enough to create a Module in Drupal 8.
Now we have a blank module with us, let’s create a Service in it. To create a service we need to add a *.services.yml file like this “my_module.services.yml”
my_module.services.yml
services: my_module.myservice: class: Drupal\my_module\MyService
So if you see the above file, “my_module.myservice” is the module_name.service_machinename for our service, you can give whatever name you want and it has a “class” parameter that shows the path of a Class file called “MyService”. We need to create the same inside the “src” folder. Let’s do that now.
MyService.php
<?php namespace Drupal\my_module; class MyService { public function myLogic() { return "My Logic Result"; } }
A service is nothing but a Simple PHP Class with some functions in it. So I have created a “MyService” Class with a function called “myLogic“. Now we have a service ready with us.
Let’s see how to use them in a Controller, but wait, we don’t controller yet, so Let’s create it first.
To create a Controller, we need a *.routing.yml file, so let’s create it.
my_module.routing.yml
my_module.mycontroller: path: /mycontrollerindex defaults: _controller: Drupal\my_module\Controller\MyController::index _title: My Controller Index requirements: _permission: 'access content'
Now, we need to create a “Controller” folder and add the “MyController” class as mentioned in the above file _controller. Let’s create the MyController.php file and inject our service into it.
MyController.php
<?php namespace Drupal\my_module\Controller; use Drupal\Core\Controller\ControllerBase; use Drupal\my_module\MyService; use Symfony\Component\DependencyInjection\ContainerInterface; class MyController extends ControllerBase { protected $my_service; public static function create(ContainerInterface $container) { return new static ( $container->get('my_module.myservice') ); } public function __construct(MyService $my_service) { $this->my_service = $my_service; } public function index() { return [ '#type' => 'markup', '#markup' => $this->my_service->myLogic() ]; } }
So to use our custom service ie., “my_module.myservice” we need to inject it as shown in the above file. As we are extending the ControllerBase, we need to override the “create()” method and get the service as shown in line no.15, and pass it to the __constrctor() as shown in line no.20. Now, we have created the object for our service and it is available in this variable “$this->my_service“. Also, see line no.26, we are calling our custom service function there.
Here is the output of our script (screenshot that shows the myLogic() return value):
You can also download this example module from my git repository: