{
    "slug": "ioc_container",
    "term": "IoC Container",
    "category": "quality",
    "difficulty": "intermediate",
    "short": "An Inversion of Control container automatically resolves and injects class dependencies — you declare what a class needs, the container figures out how to create it, eliminating manual dependency wiring.",
    "long": "An IoC (Inversion of Control) container, also called a DI (Dependency Injection) container or service container, maintains a registry of how to construct objects. When you request a class, the container inspects its constructor type hints, recursively resolves each dependency, and returns a fully-constructed instance. In Laravel, the service container is the central registry — type-hint an interface in a controller constructor and the container injects the concrete implementation bound to that interface. Symfony's DI component reads service definitions from YAML/XML/PHP configuration. Binding patterns: concrete bindings (App::bind(UserRepository::class, EloquentUserRepository::class)); singleton bindings (App::singleton(Cache::class, RedisCache::class) — same instance reused); factory bindings (App::bind(Report::class, fn($app) => new Report($app->make(DB::class), config('reports')))); contextual bindings (inject different implementations depending on which class is requesting the dependency).",
    "aliases": [
        "DI container",
        "service container",
        "dependency injection container",
        "IoC",
        "inversion of control container",
        "Laravel container",
        "Symfony DI"
    ],
    "tags": [
        "ioc-container",
        "dependency-injection",
        "architecture",
        "laravel",
        "symfony",
        "php"
    ],
    "misconception": "A DI container is required to use dependency injection. Dependency injection is just passing dependencies through constructors or method parameters — no container required. A container automates the wiring for large applications with many classes and deep dependency trees. For small scripts or simple classes, constructor injection without a container is perfectly valid DI. The container solves the 'who constructs the dependencies?' question at scale.",
    "why_it_matters": "IoC containers eliminate the most tedious part of dependency injection at scale: manually constructing object graphs. Without a container, constructing a controller with five dependencies, each with their own dependencies, requires deeply nested new() calls in bootstrap code. With a container, type-hint the interface and it appears. More importantly, the container enables interface binding — you can swap EloquentUserRepository for InMemoryUserRepository in tests by changing one binding, without modifying any class that uses UserRepository. This is the foundation of testable PHP application architecture.",
    "common_mistakes": [
        "Injecting the container itself into classes — this is the Service Locator antipattern; inject specific dependencies, not the container.",
        "Binding concrete classes to concrete classes — bind interfaces to implementations so you can swap implementations without changing dependent code.",
        "Not using singleton binding for expensive-to-construct services — database connections and HTTP clients should be shared instances, not recreated per-request.",
        "Overusing the container for simple value objects — inject config values directly, not through the container."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "dependency_injection",
        "mvc_pattern",
        "service_worker",
        "separation_of_concerns"
    ],
    "prerequisites": [],
    "refs": [
        "https://laravel.com/docs/container",
        "https://symfony.com/doc/current/components/dependency_injection.html"
    ],
    "bad_code": "// Service locator antipattern — container injected into class\nclass OrderService {\n    public function __construct(private Container $container) {}\n\n    public function process(int $id): void {\n        // Hidden dependency — unclear what this class needs\n        $repo = $this->container->make(OrderRepository::class);\n        $mail = $this->container->make(Mailer::class);\n    }\n}",
    "good_code": "// Constructor injection — dependencies explicit, testable\nclass OrderService {\n    public function __construct(\n        private OrderRepository $orders,\n        private Mailer          $mailer,\n    ) {}\n\n    public function process(int $id): void {\n        $order = $this->orders->find($id); // injected dependency\n        $this->mailer->send(new OrderConfirmed($order));\n    }\n}\n\n// ServiceProvider — bind interface to implementation once\npublic function register(): void {\n    $this->app->singleton(OrderRepository::class, EloquentOrderRepository::class);\n    $this->app->singleton(Mailer::class, SmtpMailer::class);\n}",
    "quick_fix": "Type-hint interfaces in constructors, bind interface to implementation once in a ServiceProvider: $this->app->bind(UserRepo::class, EloquentUserRepo::class) — the container handles the rest",
    "severity": "info",
    "effort": "medium",
    "created": "2026-03-23",
    "updated": "2026-04-05",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/ioc_container",
        "html_url": "https://codeclaritylab.com/glossary/ioc_container",
        "json_url": "https://codeclaritylab.com/glossary/ioc_container.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": "[IoC Container](https://codeclaritylab.com/glossary/ioc_container) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/ioc_container"
            }
        }
    }
}