Skip to main content
Home
Drupal life hacks

Main navigation

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

Breadcrumb

  1. Home

Dependency Injection Without Pain: Symfony, Laravel, and Drupal Explained

By admin, 3 January, 2026
Dependency Injection Without Pain: Symfony, Laravel, and Drupal Explained

Dependency Injection Without Pain: Symfony, Laravel, and Drupal Explained

Introduction

Dependency Injection (DI) is a cornerstone of modern PHP frameworks, but many developers—especially those coming from Drupal—find it confusing. Why inject services instead of calling them directly? How do DI containers differ between Drupal, Symfony, and Laravel?

In this article, we’ll break it down with practical examples, showing how to use DI without headaches across these three systems.


1. What is Dependency Injection?

Simply put:

Dependency Injection is a way to give a class the objects it needs rather than letting the class create them itself.

Benefits:

  • Loose coupling – classes don’t need to know implementation details
  • Testability – dependencies can be mocked
  • Flexibility – change services without modifying the consumer

2. Drupal DI: Services and Container

2.1 Define a Service

my_module.services.yml

services:
  my_module.logger:
    class: Drupal\my_module\Service\UserLogger
    arguments: ['@logger.channel.user']

2.2 Inject Service in a Controller

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\my_module\Service\UserLogger;

class MyController extends ControllerBase {
  public function __construct(private UserLogger $logger) {}

  public function logUser(): string {
    $this->logger->log('Test message');
    return 'Logged!';
  }
}

✅ Key Points

  • Drupal uses Symfony DI container
  • Services can be injected in controllers, forms, or other services
  • Reduces use of global functions (\Drupal::service())

3. Symfony DI: Explicit and Powerful

3.1 Define Service in YAML

services:
  App\Service\UserLogger:
    arguments: ['@logger']

3.2 Inject in Controller

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Service\UserLogger;

class UserController extends AbstractController {
  public function index(UserLogger $logger) {
    $logger->log('User accessed page');
    return $this->json(['status' => 'ok']);
  }
}

✅ Key Points

  • DI is core philosophy
  • All services are typed and resolved automatically
  • Works well with autowiring and autoconfiguration

4. Laravel DI: Service Providers and Constructor Injection

4.1 Bind Service in ServiceProvider

$this->app->bind(UserLogger::class, function($app) {
    return new UserLogger($app->make('log'));
});

4.2 Inject in Controller

namespace App\Http\Controllers;

use App\Services\UserLogger;

class UserController extends Controller {
  public function index(UserLogger $logger) {
    $logger->log('User accessed page');
    return response()->json(['status' => 'ok']);
  }
}

✅ Key Points

  • Laravel auto-resolves services by type
  • Service Providers are entry points for registering dependencies
  • Less strict than Symfony, more flexible than Drupal

5. Comparison Table

AspectDrupalSymfonyLaravel
DI containerSymfony-basedSymfony-nativeLaravel-native
AutowiringYesYesYes
Manual bindingOptionalOptionalCommon
Injection in controllers✅✅✅
Injection in forms/plugins✅Limited❌

6. Practical Tips to Avoid DI Pain

  1. Always type-hint services in constructors
  2. Avoid calling global service functions (\Drupal::service())
  3. Keep services single-responsibility
  4. Use service configuration files consistently
  5. Prefer autowiring over manual injection when possible

7. Conclusion

Dependency Injection may seem tricky at first, but:

  • Drupal = DI + CMS features + Plugin API
  • Symfony = strict, typed, architectural DI
  • Laravel = developer-friendly, auto-resolving DI

Mastering DI across these three frameworks will make your code:

  • cleaner
  • testable
  • reusable

Tags

  • Drupal dependency injection
  • Symfony dependency injection
  • Laravel dependency injection
  • PHP frameworks
  • Drupal services
  • Symfony DI container
  • Laravel service provider
  • PHP modular architecture
  • Drupal Module Development
  • Laravel packages
  • Symfony services
  • event-driven architecture
  • PHP developer guide
  • DI best practices
  • cross-framework comparison

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