{
    "slug": "dependency_injection",
    "term": "Dependency Injection",
    "category": "quality",
    "difficulty": "intermediate",
    "short": "Passing dependencies into a class rather than creating them inside — makes classes testable and loosely coupled.",
    "long": "Dependency injection (DI) means a class receives its collaborators (database connection, mailer, logger) as constructor arguments or method parameters rather than instantiating them internally with new. This makes the class testable (you can pass mock collaborators in tests), configurable (swap implementations without changing the class), and loosely coupled (the class depends on an interface, not a concrete implementation). Constructor injection is the preferred form — it makes dependencies explicit and the class impossible to create in an invalid state.",
    "aliases": [
        "DI",
        "inversion of control",
        "IoC",
        "dependency inversion"
    ],
    "tags": [
        "solid",
        "oop",
        "testing",
        "architecture"
    ],
    "misconception": "Dependency injection requires a DI container or framework. DI is simply passing dependencies in rather than constructing them internally — constructor injection with no framework at all is valid DI and often simpler for smaller codebases.",
    "why_it_matters": "DI makes dependencies explicit and swappable — you can substitute a real mailer for a fake one in tests, or swap a Redis cache for an in-memory one without touching business logic. Code without DI is hard to test and tightly coupled.",
    "common_mistakes": [
        "Injecting the container itself (service locator anti-pattern) — inject specific dependencies instead.",
        "Using constructor injection for optional dependencies — use setter injection or nullable defaults for those.",
        "Newing up dependencies inside methods (new Mailer()) instead of receiving them from outside.",
        "Registering everything as a singleton when it should be transient, causing state leakage between requests."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "open_closed_principle",
        "single_responsibility",
        "god_class"
    ],
    "prerequisites": [
        "interfaces",
        "single_responsibility",
        "inversion_of_control"
    ],
    "refs": [
        "https://en.wikipedia.org/wiki/Dependency_injection",
        "https://phptherightway.com/#dependency_injection"
    ],
    "bad_code": "class OrderService {\n    public function place(Cart $cart): Order {\n        $mailer = new Mailer();       // hard-coded dependency\n        $db     = new Database();     // impossible to swap/mock\n        $db->save($cart);\n        $mailer->send($cart->user, 'Your order is placed');\n    }\n}",
    "good_code": "class OrderService {\n    public function __construct(private MailerInterface $mailer) {}\n\n    public function notify($order) {\n        $this->mailer->send($order->email, 'Order confirmed');\n    }\n}",
    "quick_fix": "Inject dependencies through the constructor rather than creating them with 'new' inside the class — this decouples the class from its dependencies",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-13",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/dependency_injection",
        "html_url": "https://codeclaritylab.com/glossary/dependency_injection",
        "json_url": "https://codeclaritylab.com/glossary/dependency_injection.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Dependency Injection](https://codeclaritylab.com/glossary/dependency_injection) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/dependency_injection"
            }
        }
    }
}