Mastering Dependency Injection: From Basics to Frameworks
Overview of Dependency Injection
Prerequisites
To get the most out of this guide, you should have a solid grasp of

Key Libraries & Tools
- Inject: A micro-framework for Python that handles dependency configuration and injection using decorators.
- FastAPI: A modern web framework with a robust, built-in DI system designed for handling request-level dependencies like database sessions.
- Pydantic: Used for data validation and settings management, often paired with DI frameworks.
Code Walkthrough: Manual vs. Automated DI
Manual Injection
In manual DI, we simply pass objects as arguments. This is the cleanest way to start.
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
def increment_age(user: User):
user.age += 1
print(f"{user.name} is now {user.age}")
# Resource creation is separated from usage
current_user = User("John", 30)
increment_age(current_user)
Using the Inject Library
When projects grow, manual injection becomes cumbersome.
import inject
@inject.params(repo='BlogRepository')
def get_all_posts(repo):
return repo.all()
def configure(binder):
binder.bind(BlogRepository, BlogRepository())
inject.configure(configure)
# Now we can call it without arguments
get_all_posts()
Syntax Notes
Pay close attention to Decorators like @inject.params. These wrap your functions to intercept calls and fill in missing arguments. In Depends() function acts as a marker within the function signature, signaling the framework to resolve that specific dependency before the endpoint logic executes.
Practical Examples
DI is indispensable for Database Connections, where you want to ensure a session is opened before a request and closed immediately after. Another powerful use case is Logging. Instead of importing a logger into every module (tight coupling), you can inject a configured logger, making it trivial to swap a standard console logger for a cloud-based one during production.
Tips & Gotchas
Avoid over-engineering. For small scripts, manual injection is usually superior because it is explicit and easy to trace. Only reach for a DI framework when you need to standardize complex life cycles or manage global resources like security scopes or external API clients.

Fancy watching it?
Watch the full video and context