Chapter 8: Dependency Injection and Dependencies
ASP.NET Core has a full DI container with singleton, scoped, and transient lifetimes. FastAPI has dependency functions. They are less formal, but request-scoped composition is excellent.
from collections.abc import Generator
from typing import Annotated
from fastapi import Depends
from sqlalchemy.orm import Session
def get_db() -> Generator[Session, None, None]:
with Session(engine) as session:
yield session
DbSession = Annotated[Session, Depends(get_db)]
@router.get("/{recipe_id}")
def get_recipe(recipe_id: int, db: DbSession):
return recipes_service.get_recipe(db, recipe_id)
Dependency functions can depend on other dependencies. This gives a graph similar to DI, but it is resolved by FastAPI for each request.
Use dependencies for:
- Database sessions.
- Current user.
- Authorization checks.
- Settings access.
- Parsed request context.
- Feature flags.
- Unit-of-work or service objects.
Do not hide all construction behind dependencies. Plain Python constructors are good. Dependency injection is a tool, not the whole architecture.