-
-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Vision
Transform dioxide from a functional DI framework into a production-ready, net-promoter-score-worthy library that developers actively recommend. This epic addresses the key gaps identified through developer feedback that prevent dioxide from being "production-ready."
The Problem
dioxide v1.0 delivers on the core MLP promise (making DIP feel inevitable), but real-world production usage reveals six critical DX gaps:
| Gap | Impact | User Pain |
|---|---|---|
| Config injection unclear | Adapters have hidden Settings() dependencies | "How do I inject config INTO my adapters?" |
| No request scope | Can't do per-request DB sessions, user context | "Not production-ready for web apps" |
| Sync-only lifecycle | Real adapters need async init (pools, clients) | "I can't use async setup for my Redis client" |
| Unhelpful error messages | "No adapter found" with no context | "I have no idea what went wrong" |
| Tedious fake creation | Hand-write every fake implementation | "So much boilerplate for testing" |
| No introspection | Can't see what's registered or debug resolution | "How do I debug my wiring?" |
Success Criteria
- Config objects can be injected into adapters without hidden imports
- REQUEST scope works with FastAPI and Flask request lifecycle
- Async
initialize()anddispose()methods fully supported - Error messages show registered adapters, current profile, and fix suggestions
- Base classes exist for common fake patterns (InMemoryRepository, FakeClock, etc.)
-
container.debug(),container.explain(Port), andcontainer.graph()available - All features have documentation with examples
- All features have comprehensive tests
Out of Scope
- IDE/LSP integration
- CLI code generators
- AOP/interceptors (post-MLP)
- XML/YAML configuration
Sub-Issues
P0: Request Scoping (Blocking for production web apps)
- Request Scoping: Define Scope.REQUEST API and ScopedContainer Interface #337 - Define Scope.REQUEST API and ScopedContainer Interface
- Request Scoping: Implement ScopedContainer and Scope Lifecycle #338 - Implement ScopedContainer and Scope Lifecycle (blocked by Request Scoping: Define Scope.REQUEST API and ScopedContainer Interface #337)
- Request Scoping: FastAPI and Flask Middleware Integration #339 - FastAPI and Flask Middleware Integration (blocked by Request Scoping: Implement ScopedContainer and Scope Lifecycle #338)
- Request Scoping: Documentation and Examples #340 - Documentation and Examples (blocked by Request Scoping: FastAPI and Flask Middleware Integration #339)
P1: Async Lifecycle (Blocking for real infrastructure adapters)
- Async Lifecycle: Verify and Fix Async Initialize/Dispose Support #341 - Verify and Fix Async Initialize/Dispose Support
- Async Lifecycle: Documentation and Patterns Guide #342 - Documentation and Patterns Guide (blocked by Async Lifecycle: Verify and Fix Async Initialize/Dispose Support #341)
P1: Better Error Messages (High-impact, low-effort DX win)
- Better Errors: Define Rich Error Message Format and Context Structure #343 - Define Rich Error Message Format and Context Structure
- Better Errors: Implement Rich Context Collection and Formatting #344 - Implement Rich Context Collection and Formatting (blocked by Better Errors: Define Rich Error Message Format and Context Structure #343)
- Better Errors: Update Exception Documentation and Troubleshooting Guide #345 - Update Exception Documentation and Troubleshooting Guide (blocked by Better Errors: Implement Rich Context Collection and Formatting #344)
P2: Config Injection (Common pain point)
- Config Injection: Define First-Class Config Object Pattern #346 - Define First-Class Config Object Pattern
- Config Injection: Implement Config Override and Registration #347 - Implement Config Override and Registration (blocked by Config Injection: Define First-Class Config Object Pattern #346)
- Config Injection: Documentation and Examples #348 - Documentation and Examples (blocked by Config Injection: Implement Config Override and Registration #347)
P2: Container Introspection (Essential for debugging)
- Container Introspection: Define Debug, Explain, and Graph API #349 - Define Debug, Explain, and Graph API
- Container Introspection: Implement Debug, Explain, and Graph Methods #350 - Implement Debug, Explain, and Graph Methods (blocked by Container Introspection: Define Debug, Explain, and Graph API #349)
- Container Introspection: Documentation and Usage Guide #351 - Documentation and Usage Guide (blocked by Container Introspection: Implement Debug, Explain, and Graph Methods #350)
P3: Fake Helpers (Nice-to-have, reduces boilerplate)
- Fake Helpers: Design Base Classes for Common Testing Patterns #352 - Design Base Classes for Common Testing Patterns
- Fake Helpers: Implement Testing Utilities Package #353 - Implement Testing Utilities Package (blocked by Fake Helpers: Design Base Classes for Common Testing Patterns #352)
- Fake Helpers: Documentation and Testing Guide Updates #354 - Documentation and Testing Guide Updates (blocked by Fake Helpers: Implement Testing Utilities Package #353)
Story Structure
Each improvement area is broken into stories that prevent shortcuts:
- API/Interface Story - Define the public API (acceptance: mypy passes)
- Implementation Story - Core logic (blocked by API story)
- Integration Story - Wire into existing systems (blocked by implementation)
- Documentation Story - Docs and examples (blocked by integration)
Technical Approach
1. Config Injection
Make Pydantic Settings (or any config class) first-class citizens that can be injected via constructor parameters, eliminating hidden Settings() calls inside adapters.
2. Request Scoping
Add Scope.REQUEST that integrates with web framework middleware to provide per-request instances that are automatically cleaned up.
3. Async Lifecycle
The @lifecycle decorator already validates async methods. This work ensures the container properly awaits them during start() and stop().
4. Better Error Messages
Enrich AdapterNotFoundError and ServiceNotFoundError with:
- List of registered adapters for the port
- Current active profile
- Suggested fixes with code examples
5. Fake Helpers
Provide reusable base classes:
InMemoryRepository[T]- Generic CRUD fakeFakeClock- Controllable timeFakeEventBus- Captured eventsFakeHttpClient- Recorded requests
6. Container Introspection
Add debugging methods:
container.debug()- Print registered componentscontainer.explain(Type)- Show resolution chaincontainer.graph()- Return dependency graph (Mermaid format)
Links
- MLP Vision:
docs/MLP_VISION.md - Testing Guide:
docs/TESTING_GUIDE.md - Current Scope Implementation:
python/dioxide/scope.py - Current Lifecycle:
python/dioxide/lifecycle.py - Current Exceptions:
python/dioxide/exceptions.py