Skip to main content
Home
Drupal life hacks

Main navigation

  • Drupal
  • React
  • WP
  • Contact
  • About
User account menu
  • Log in

Breadcrumb

  1. Home

Utilizing Services in Drupal: Static Access vs. Dependency Injection

By admin, 20 May, 2024

In Drupal, services can be utilized in two primary ways: statically and via dependency injection. Each method has its own applications and advantages. Here’s a detailed explanation of both approaches.

1. Using Services Statically

Static usage involves accessing services directly through the service container. This is commonly done in cases where the class is not a service and you cannot inject dependencies.

Example:

use Drupal::service;
// Access the 'module_handler' service.
$module_handler = \Drupal::service('module_handler');
// Use the service.
$module_handler->invokeAll('help');

Advantages:

- Simplicity: Easy to use anywhere in the code.
- Quick implementation: No need to modify class signatures and constructors.

Disadvantages:

- Testing difficulties: Harder to write unit tests since using global state makes mocking services challenging.
- Implicit dependencies: Dependencies are not obvious from the class signature, which can complicate code maintenance.

2. Dependency Injection

Dependency injection is the more preferred approach as it makes a class’s dependencies explicit and facilitates testing.

Example:

1. Define the service in YAML configuration:

services:
 my_module.my_service:
   class: Drupal\my_module\MyService
   arguments: ['@module_handler']

2. Use dependency injection in the class:

namespace Drupal\my_module;
use Drupal\Core\Extension\ModuleHandlerInterface;
class MyService {
 protected $moduleHandler;
// Inject dependency via the constructor.
 public function __construct(ModuleHandlerInterface $module_handler) {
   $this->moduleHandler = $module_handler;
 }
public function doSomething() {
   // Use the injected service.
   $this->moduleHandler->invokeAll('help');
 }
}

3. Use the service in another class:

namespace Drupal\my_module\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\my_module\MyService;
class MyController {
 protected $myService;
public function __construct(MyService $my_service) {
   $this->myService = $my_service;
 }
// Controller factory for dependency injection.
 public static function create(ContainerInterface $container) {
   return new static(
     $container->get('my_module.my_service')
   );
 }
public function myPage() {
   // Use the injected service.
   $this->myService->doSomething();
 }
}

Advantages:

- Easier testing: Easier to write unit tests with mocked dependencies.
- Explicit dependencies: Class dependencies are visible from its signature, making the code easier to understand and maintain.
- Flexibility: Easy to replace dependencies (e.g., for testing or configuration).

Disadvantages:

- Configuration complexity: Requires more initial setup.
- Dependencies must be available when the class instance is created, which might require code changes.

Conclusion

Using services via dependency injection is recommended in most cases due to its clear advantages in maintainability and testability. Static service usage can be useful in smaller scenarios or when dependency injection is not feasible.

Tags

  • #Drupal Planet

Comments

About text formats

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Powered by Drupal