> ## Documentation Index
> Fetch the complete documentation index at: https://genai.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Dependency Injection

> Learn the concepts of Dependency, Dependency Injection (DI), Inversion of Control (IoC), and how FastAPI uses Depends() to build loosely coupled, reusable applications.

## Introduction

Dependency Injection (DI) is one of the most important concepts used in production-grade FastAPI applications. It helps build applications that are:

* Reusable
* Loosely coupled
* Easier to test
* Easier to maintain

Before learning FastAPI's `Depends()`, it's important to understand three related concepts:

* Dependency
* Dependency Injection (DI)
* Inversion of Control (IoC)

Although these concepts are closely related, they are **not the same**.

## What is a Dependency?

A **dependency** is any object, resource, or service that another object needs in order to perform its work.

For example, an endpoint may depend on:

* Database Session
* Repository
* Service
* Current User
* Configuration
* Logger
* External API Client

Simply put,

> **A dependency is something your code needs to do its job.**

## What is Dependency Injection (DI)?

**Dependency Injection (DI)** is a design pattern where an object or function receives the dependencies it needs from an external source instead of creating them internally.

Instead of saying,

> "I'll create everything myself."

your code simply says,

> "Give me what I need."

DI focuses only on **providing (injecting) dependencies**.

It does **not** define:

* Who creates them.
* Who manages them.
* Who destroys them.

## Simple Python Example

Without Dependency Injection:

```python theme={null}
class Printer:
    def print(self, message):
        print(message)

class StudentService:
    def __init__(self):
        self.printer = Printer()

    def generate_report(self):
        self.printer.print("Student Report")
```

With Dependency Injection:

```python theme={null}
class Printer:
    def print(self, message):
        print(message)

class StudentService:
    def __init__(self, printer: Printer):
        self.printer = printer

    def generate_report(self):
        self.printer.print("Student Report")

printer = Printer()

service = StudentService(printer)
```

The service no longer creates its own dependency.

Instead, the dependency is supplied from outside.

This makes the code:

* Loosely coupled
* Easier to test
* Easier to reuse
* Easier to maintain

## FastAPI Already Performs Injection

Even before using `Depends()`, FastAPI is already injecting values into your endpoint functions.

```python theme={null}
from fastapi import FastAPI

app = FastAPI()

@app.get("/students/{student_id}")
def get_student(
    student_id: int,
    active: bool = True
):
    return {
        "student_id": student_id,
        "active": active
    }
```

Request:

```http theme={null}
GET /students/101?active=false
```

FastAPI automatically injects:

| Function Parameter | Source          |
| ------------------ | --------------- |
| `student_id`       | Path Parameter  |
| `active`           | Query Parameter |

Conceptually, FastAPI performs something similar to:

```python theme={null}
student_id = request.path_params["student_id"]
active = request.query_params["active"]

get_student(
    student_id,
    active
)
```

You never write this extraction code yourself.

FastAPI supplies the required values automatically.

This introduces the idea of **injection**.

Later, FastAPI extends this same mechanism to inject application resources using `Depends()`.

## What is Inversion of Control (IoC)?

**Inversion of Control (IoC)** is a design principle where the responsibility of controlling object creation and application flow is delegated to a framework instead of your application.

Without IoC:

```text theme={null}
Application
    │
    ├── Create Database
    ├── Create Repository
    ├── Create Service
    └── Call Methods
```

With IoC:

```text theme={null}
FastAPI
    │
    ├── Create Database
    ├── Create Repository
    ├── Resolve Dependencies
    └── Call Your Endpoint
```

IoC answers:

> **Who controls object creation and application flow?**

Answer:

> **The framework.**

## Relationship Between IoC and DI

Although often used together, they solve different problems.

| IoC                                           | DI                                         |
| --------------------------------------------- | ------------------------------------------ |
| Design Principle                              | Design Pattern                             |
| Controls object creation and application flow | Supplies required dependencies             |
| Answers **Who is in control?**                | Answers **How are dependencies provided?** |

Think of them like this:

```text theme={null}
IoC
 │
 └── Framework controls the application

DI
 │
 └── Objects receive dependencies from outside
```

Frameworks such as **FastAPI**, **Spring**, and **ASP.NET Core** use both concepts together.

## Real-World Analogy

Imagine a chef working in a restaurant.

Without IoC:

The chef must:

* Buy vegetables
* Arrange utensils
* Prepare ingredients
* Cook

With IoC:

Restaurant management prepares everything.

The chef only cooks.

| Restaurant            | FastAPI      |
| --------------------- | ------------ |
| Restaurant Management | Framework    |
| Chef                  | Endpoint     |
| Prepared Ingredients  | Dependencies |

The restaurant management controlling the workflow is **IoC**.

Providing prepared ingredients to the chef is **Dependency Injection**.

## How FastAPI Uses Dependency Injection

FastAPI provides a built-in Dependency Injection system through **`Depends()`**.

```python theme={null}
from fastapi import Depends

def get_db():
    ...

@app.get("/students")
def get_students(
    db = Depends(get_db)
):
    ...
```

When a request arrives, FastAPI:

1. Resolves the dependency.
2. Injects it into the endpoint.
3. Cleans it up after the request (if required).

The endpoint simply receives what it needs.

FastAPI commonly injects:

* Database Sessions
* Repositories
* Services
* Current User
* Authentication
* Configuration
* External Clients
* Logger

## Dependency Resolution Flow

```text theme={null}
HTTP Request
      │
      ▼
FastAPI
      │
      ▼
Resolve Dependencies
      │
      ├── get_db()
      ├── get_repository()
      ├── get_service()
      └── get_current_user()
      │
      ▼
Inject into Endpoint
      │
      ▼
Execute Endpoint
      │
      ▼
Cleanup
```

## Benefits

Dependency Injection helps build applications that are:

* Loosely Coupled
* Modular
* Reusable
* Easier to Test
* Easier to Maintain
* Easier to Extend

## Summary

| Concept              | Description                                                             |
| -------------------- | ----------------------------------------------------------------------- |
| Dependency           | Something your code needs to perform its work                           |
| Dependency Injection | Providing dependencies from outside instead of creating them internally |
| Inversion of Control | The framework controls object creation and application flow             |
| Depends()            | FastAPI's mechanism for injecting dependencies                          |

## Key Takeaways

* A dependency is anything your code needs.
* Dependency Injection means receiving dependencies instead of creating them.
* IoC means the framework controls the application's workflow and object lifecycle.
* DI and IoC are related but different concepts.
* FastAPI injects request data automatically.
* `Depends()` extends this mechanism to inject reusable application resources.

## Frequently Asked Questions

<Accordion title="Is Dependency Injection the same as Inversion of Control?">
  No.

  * **IoC** is a design principle.
  * **DI** is a design pattern.

  IoC answers **who controls the application**, while DI answers **how dependencies are provided**.
</Accordion>

<Accordion title="Is Dependency Injection an implementation of IoC?">
  Not exactly.

  A more accurate statement is:

  > **Dependency Injection is one of the most common techniques used to achieve Inversion of Control.**

  DI and IoC are different concepts that are frequently used together.
</Accordion>

<Accordion title="Can Dependency Injection exist without IoC?">
  Yes.

  Example:

  ```python theme={null}
  db = Database()
  service = UserService(db)
  ```

  You created the dependency yourself and injected it manually.

  This is **Dependency Injection without IoC** because your application still controls object creation.
</Accordion>

<Accordion title="Can IoC exist without Dependency Injection?">
  Yes.

  A framework can control object creation and application flow using callbacks, event handlers, plugins, or other techniques without using Dependency Injection.
</Accordion>

<Accordion title="Does Dependency Injection create objects?">
  No.

  Dependency Injection is only about **supplying dependencies**.

  Who creates those dependencies depends on the application or framework.
</Accordion>

<Accordion title="Why does FastAPI create dependencies then?">
  Because FastAPI combines **IoC** and **Dependency Injection**.

  FastAPI:

  * Resolves dependencies
  * Creates objects when needed
  * Injects them into your endpoint
  * Cleans them up after the request

  Creating and managing objects is part of FastAPI's IoC behavior, while supplying them to your code is Dependency Injection.
</Accordion>

<Accordion title="Is FastAPI already using Dependency Injection before Depends()?">
  Yes.

  FastAPI already injects request data into endpoint parameters, including:

  * Path Parameters
  * Query Parameters
  * Request Bodies
  * Headers
  * Cookies
  * Form Data
  * Uploaded Files

  `Depends()` extends this same mechanism to inject higher-level application resources such as database sessions, repositories, services, and authentication.
</Accordion>

<Accordion title="Why should I use Dependency Injection?">
  Dependency Injection helps build applications that are:

  * Loosely coupled
  * Easier to test
  * More reusable
  * Easier to maintain
  * Easier to extend
</Accordion>

<Accordion title="What is the difference between request data injection and Depends() injection?">
  Both use the same idea—FastAPI supplies what your endpoint needs.

  **Request Data Injection** provides values extracted from the HTTP request:

  * Path Parameters
  * Query Parameters
  * Headers
  * Cookies
  * Request Body

  ```python theme={null}
  @app.get("/students/{student_id}")
  def get_student(student_id: int, active: bool = True):
      ...
  ```

  **Dependency Injection with `Depends()`** provides reusable application resources:

  * Database Sessions
  * Services
  * Repositories
  * Current User
  * Configuration

  ```python theme={null}
  @app.get("/students")
  def get_students(
      db = Depends(get_db)
  ):
      ...
  ```

  The difference is **what is being injected**, not **how** it is injected.
</Accordion>
