Call Us Today! (443) 500-7624
The website development world is truly an amazing world, developers should always keep their skills up to date by taking courses and getting certifications, and training which can help them to accomplish great things, in the web technology space.
In today’s article, we are going to talk a bit more about services in Drupal 8, we will learn how to use one, step by step.
Accessing and using services requires a developer to use, something called Dependency Injection. Setter methods are used to inject services, or they can also be passed, as an argument to a constructor, this way there is no need to call out to the global service container.
Alright, so let’s delve into the structure of a service file, the your_module_name.services.yml file will define the services you would like to use. This file is automatically used and detected by Drupal when it is placed in the root of your_module directory.
It looks something like this, you can find the complete list of services on the core.services.yml file.
parameters:
session.storage.options:
gc_probability: 1
gc_divisor: 100
twig.config:
debug: false
renderer.config:
required_cache_contexts: [‘languages:language_interface’, ‘theme’, ‘user.permissions’]
auto_placeholder_conditions:
max-age: 0
factory.keyvalue:
default: keyvalue.database
http.response.debug_cacheability_headers: false
factory.keyvalue.expirable:
default: keyvalue.expirable.database
filter_protocols:
– http
– https
– ftp
– news
– nntp
– tel
cors.config:
enabled: false
supportsCredentials: false
tempstore.expire: 604800
services:
# Simple cache contexts, directly derived from the request context.
cache_context.ip:
class: Drupal\Core\Cache\Context\IpCacheContext
arguments: [‘@request_stack’]
tags:
– { name: cache.context }
cache_context.headers:
class: Drupal\Core\Cache\Context\HeadersCacheContext
arguments: [‘@request_stack’]
tags:
– { name: cache.context }
cache_context.cookies:
class: Drupal\Core\Cache\Context\CookiesCacheContext
arguments: [‘@request_stack’]
tags:
– { name: cache.context }
cache_context.session:
class: Drupal\Core\Cache\Context\SessionCacheContext
arguments: [‘@request_stack’]
tags:
– { name: cache.context}
cache_context.session.exists:
class: Drupal\Core\Cache\Context\SessionExistsCacheContext
arguments: [‘@session_configuration’, ‘@request_stack’]
tags:
– { name: cache.context}
config.storage.sync:
alias: config.storage.staging
Remember that this is a .yml file, therefore, it is very important that you pay attention to indentation here. Before we move on let’s talk about the properties of a service, to understand the services .yml file a bit better.
The first property is alias, which is just the alias name of the service which you intend to use for your custom code. Aliasing services would give you the ability to access them, through a shortcut created through an alias.
The next property of a service file is the calls, which are used for setter injection; it is important to note that there are three different types of injections known as the constructor injection, which is used by adding an argument to the constructor signature, which can accept the dependency. The constructor injection is the most common way of injecting dependencies in Drupal 8.
The constructor injection allows developers to ensure that required dependencies are present when a class that cannot be constructed without the dependency is used. The constructor injection though can be problematic when a class needs to be overridden or extended.
The setter injection is another way of injecting dependencies into a class, by setting a setter method which accepts the dependency, then we are using the setter injection. Optional dependencies are better injected with setter injection because the setter does not have to be called if the dependency is not needed. With setter injections, you don’t have to call them but just once, you can make multiple calls, to the same setter injection.
The setter injection though can also force you to work in the dark, because a developer doesn’t have a way to know if the dependency has been changed during the lifetime of the object. The only way of knowing this information is to explicitly write the setter method, which would check if the dependency has already been called. In order to find out if any required dependency has been injected a developer has to also add checks when he/she is using the setter injection method.
The other type of dependency injection is known as the property injection, which is like setter injection; however, with property injection, there is no way to control when a dependency has been set, because, during the object’s lifetime, it can be changed. Before using a dependency, which has been injected via the property injection method, a developer has to write code, which would explicitly test the class instance; because developers will not be sure which dependency is being used.
Alright, we have arrived at the end of our conversation, we will continue talking about this topic on the very next article stay tuned.
Thank you for reading this article!!!
\Drupal\Component\Plugin\PluginManagerInterface,Implements all plugin managers, and this piece of code extends these three pieces of code, which are the basis for any new plugin manager.
\Drupal\Component\Plugin\Discovery\DiscoveryInterface, \Drupal\Component\Plugin\Factory\FactoryInterface and, \Drupal\Component\Plugin\Mapper\MapperInterface.The plugin.manager.* a piece of code is used to generate plugin manager services and from the service container, a copy of the plugin manager can be requested. Example:
$example_manager = \Drupal::service('plugin.manager.example');Once a developer has identified the plugin manager needed, to complete a task, then that developer has to start, by locating the name of the plugin manager service he/she needs. The controller will be the place where, a developer can inject their plugin manager services, and this is the Drupal way of doing things. The code below is a controller file, located under custom_module/src/Controller, it is very important that you get those names and file directory correct, for Drupal to recognize your controller and plugin.
<?php namespace Drupal\plugin_type_example\Controller; use Drupal\Core\Controller\ControllerBase; use Drupal\plugin_type_example\SandwichPluginManager; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Controller for our example pages. */ class PluginTypeExampleController extends ControllerBase { /** * The sandwich plugin manager. * * We use this to get all of the sandwich plugins. * * @var \Drupal\plugin_type_example\SandwichPluginManager */ protected $sandwichManager; /** * Constructor. * * @param \Drupal\plugin_type_example\SandwichPluginManager $sandwich_manager * The sandwich plugin manager service. We're injecting this service so that * we can use it to access the sandwich plugins. */ public function __construct(SandwichPluginManager $sandwich_manager) { $this->sandwichManager = $sandwich_manager; } /** * {@inheritdoc} * * Override the parent method so that we can inject our sandwich plugin * manager service into the controller. * * For more about how dependency injection works read https://www.drupal.org/node/2133171 */ public static function create(ContainerInterface $container) { // Inject the plugin.manager.sandwich service that represents our plugin // manager as defined in the plugin_type_example.services.yml file. return new static($container->get('plugin.manager.sandwich')); } }All defined plugins have information that can aid our application development to move forward faster. All that information from defined plugins is available to developers when they can make calls to the getDefinitions method. Enabled modules, can be used to locate all plugin definitions of the type in question, through the discovery handler . When the discovery handler is not used to retrieve data, then the DefaultPluginManager is used to retrieve the data from the cache if the data is available there. A good example of is in the code below, watch how the definitions of a plugin can be obtained in the code.
// Get the list of all the sandwich plugins defined on the system from the // plugin manager. Note that at this point, what we have is *definitions* of // plugins, not the plugins themselves. $sandwich_plugin_definitions = $this->sandwichManager->getDefinitions(); // Let's output a list of the plugin definitions we now have. $items = array(); foreach ($sandwich_plugin_definitions as $sandwich_plugin_definition) { // Here we use various properties from the plugin definition. These values // are defined in the annotation at the top of the plugin class: see // \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich. $items[] = t("@id (calories: @calories, description: @description )", array( '@id' => $sandwich_plugin_definition['id'], '@calories' => $sandwich_plugin_definition['calories'], '@description' => $sandwich_plugin_definition['description'], )); } // Add our list to the render array. $build['plugin_definitions'] = array( '#theme' => 'item_list', '#title' => 'Sandwich plugin definitions', '#items' => $items, );When a list of plugin types is desired by a developer he/she may want to use the method above to accomplish this task. The unique ID of a plugin can be utilized in order to retrieve the definition of the plugin in question, calling the getDefinition($plugin_id) method. // If we want just a single plugin definition, we can use getDefinition(). // This requires us to know the ID of the plugin we want. This is set in the // annotation on the plugin class: see \Drupal\plugin_type_example\Plugin\Sandwich\ExampleHamSandwich. $ham_sandwich_plugin_definition = $this->sandwichManager->getDefinition('meatball_sandwich'); In order to instantiate and use an individual plugin object, the createInstance($plugin_id) method can be used. It is not good practice to instantiate a plugin object directly, instead, the plugin manager should be used to do so. Understanding how instances of a plugin are created requires that you see it in action, in the code below.
// To get an instance of a plugin, we call createInstance() on the plugin // manager, passing the ID of the plugin we want to load. Let's output a // list of the plugins by loading an instance of each plugin definition and // collecting the description from each. $items = array(); // The array of plugin definitions is keyed by plugin id, so we can just use // that to load our plugin instances. $sandwich_plugin_definitions = $this->sandwichManager->getDefinitions(); foreach ($sandwich_plugin_definitions as $plugin_id => $sandwich_plugin_definition) { // We now have a plugin instance. From here on it can be treated just as // any other object; have its properties examined, methods called, etc. $plugin = $this->sandwichManager->createInstance($plugin_id); $items[] = $plugin->description(); }All the code on this tutorial was taken from Drupalize.me. Thank you for reading this article!!!
Phone: (443) 500-7624
Email: admin@kinginfolife.com
Address: Baltimore, MD 21206
All Rights Reserved | KING INFO LIFE