Reference / Symfony
/

Dependency Injection

Symfony resolves and injects services into your code via the container, instead of you newing things up.

Foundational
  • A "service" is just a class managed by the container — typically with logic you want to share.
  • Constructor injection is the default. Type-hint a service in your constructor and Symfony provides it.
  • Autowiring uses the type-hint to figure out which concrete class to inject, no config required.
  • Autoconfiguration applies tags automatically based on interfaces (e.g. EventSubscriberInterface).
  • When more than one class implements an interface, you must alias or bind the right one explicitly.
  • Services are singletons by default — one instance per request. Mark them shared: false to change that.
// src/Service/Mailer.php
class Mailer
{
    public function __construct(private LoggerInterface $logger) {}
}

// Anywhere else
class NotifyController
{
    public function __construct(private Mailer $mailer) {}
}

Common gotchas

  • Don't confuse autowiring (resolving constructor args by type) with autoconfiguration (applying tags by interface). They run together but do different things.
  • Public vs private services: in Symfony 4+ services are private by default. You inject them — you do not pull them from `\$container->get()`.
  • Circular dependencies fail at compile time, not runtime. Read the error — it usually points at the cycle.