You can see module hooks are still in a procedural way to utilize a dependent service
That's why we have a static Drupal Class, it can get a service in a procedural context.
How to access a service in module hooks?
Drupal::service('{service id}') or
service accessors like Drupal::request(), Drupal::currentUser(), Drupal::entityManager().
It is providing a uniform way of getting any services inside hooks and it eases the transition from procedural code to injected oops code.
How a container get services in drupal?
The container is built by the kernel and passed to the static Drupal Class and the container gets all the services from the system by the below methods
1. \Drupal\Core\CoreServiceProvider
2. the service providers of enabled modules
3. any other service providers defined in $GLOBALS['conf']['container_service_providers'].
How you can improve the dependent service access from module ?
function hook_do_stuff() {
$lock = lock()
->acquire('stuff_lock');
// ...
}
// Correct procedural code.
function hook_do_stuff() {
$lock = \Drupal::lock()
->acquire('stuff_lock');
// ...
}
// The preferred way: dependency injected code.
function hook_do_stuff() {
// Move the actual implementation to a class and instantiate it.
$instance = new StuffDoingClass(\Drupal::lock());
$instance
->doStuff();
// Or, even better, rely on the service container to avoid hard coding a
// specific interface implementation, so that the actual logic can be
// swapped. This might not always make sense, but in general it is a good
// practice.
\Drupal::service('stuff.doing')
->doStuff();
}
interface StuffDoingInterface {
public function doStuff();
}
class StuffDoingClass implements StuffDoingInterface {
protected $lockBackend;
public function __construct(LockBackendInterface $lock_backend) {
$this->lockBackend = $lock_backend;
}
public function doStuff() {
$lock = $this->lockBackend
->acquire('stuff_lock');
// ...
}
Comments