litestar-dependency-injection
SKILL.md
Dependency Injection
Execution Workflow
- Choose the contract to inject first: settings object, service, repository, session, current user, or request-derived value.
- Pick the narrowest scope that should own it: app, router, controller, or handler.
- Implement the provider as a callable wrapped in
Provide, choosing async, sync, or generator form based on lifecycle needs. - Keep the dependency key identical to the injected parameter name.
- Use overrides intentionally at lower scopes and in tests.
- Mark special cases with
Dependency(...)when validation, defaults, or OpenAPI behavior need to be explicit. - Verify cleanup behavior for generator dependencies and startup-time failure for missing explicit dependencies.
Core Rules
- Register dependencies at the narrowest scope that matches their reuse boundary.
- Keep dependency keys stable and descriptive:
settings,db_session,current_user,tenant,clock. - Keep injected annotations runtime-importable. Avoid hiding injected types behind
TYPE_CHECKINGunless you also provide a working runtime signature namespace. - Accept keyword arguments and
selfin providers, never positional-only runtime arguments. - Match the provider key and the consumer parameter name exactly.
- Prefer injecting services and repositories instead of raw transport objects unless the dependency is explicitly request-derived.
- Avoid hidden mutable singletons. If state must be shared, make lifecycle and mutability obvious.
Scope Selection
Litestar resolves dependencies from outer to inner scope, with lower scopes overriding higher ones when the same key is reused.
- App scope: global settings, shared clients, top-level service factories.
- Router scope: feature-area dependencies shared across related routes.
- Controller scope: controller-local services or authorization context.
- Handler scope: per-endpoint customization and local overrides.
Choose the lowest scope that still matches the reuse boundary. Reusing the same key is an intentional override contract, not a naming accident.
Provider Selection
- Use async providers for I/O-bound work that is naturally asynchronous.
- Use sync providers only when the work is truly synchronous.
- Set
sync_to_thread=Truefor blocking I/O or CPU-heavy sync providers. - Set
sync_to_thread=Falsefor cheap, non-blocking sync providers to document intent and avoid warnings. - Use generator providers when setup and cleanup belong to the same logical resource.
- Use callable instances when constructor-time configuration is required but invocation should still be DI-managed.
Reference Files
Read only the sections you need:
- For scope examples, provider forms, request-derived values,
yieldcleanup, overrides, caching, nested dependency graphs, and service wiring patterns, read references/provider-patterns.md. - For
Annotated[..., Dependency(...)]usage, validation control, OpenAPI-safe defaults, and fail-fast explicit dependency markers, read references/dependency-markers.md.
Recommended Defaults
- Keep validation enabled unless the provider is trusted and the performance or type-system tradeoff is justified.
- Keep dependency graphs shallow enough to reason about quickly.
- Compose stable layers: settings -> client/session -> repository -> service.
- Use request-derived providers as translation boundaries from transport inputs to domain types.
- Reuse the same dependency keys in tests to swap in fakes without touching handler code.
Anti-Patterns
- Registering everything at app scope because it is convenient.
- Using dependencies as an opaque service locator with unclear names like
dep1. - Returning mutable global singletons from providers and mutating them per request.
- Performing blocking I/O in sync providers without
sync_to_thread=True. - Using
skip_validation=Truebroadly instead of fixing the type boundary. - Repeating lookup logic in handlers when a request-derived provider should own it.
Validation Checklist
- Confirm every injected parameter name matches a registered dependency key.
- Confirm the chosen scope matches reuse and override needs.
- Confirm sync providers declare the right
sync_to_threadbehavior. - Confirm generator dependencies always close, even on exceptions.
- Confirm nested provider graphs stay readable and testable.
- Confirm
Dependency(default=...)is used when fallback dependencies must stay out of OpenAPI. - Confirm explicit
Dependency()markers catch missing required wiring at startup. - Confirm tests can override keys cleanly without monkeypatching internals.
Cross-Skill Handoffs
- Use
litestar-databasesfor SQLAlchemy or Piccolo session provisioning. - Use
litestar-testingfor dependency override patterns and client-based verification. - Use
litestar-securityorlitestar-authenticationwhen DI is carrying auth context. - Use
litestar-routingwhen the main issue is route/controller structure rather than service wiring.
Litestar References
Weekly Installs
12
Repository
alti3/litestar-skillsGitHub Stars
5
First Seen
13 days ago
Security Audits
Installed on
opencode12
gemini-cli12
github-copilot12
codex12
kimi-cli12
cursor12