Introduction
Framefox provides a comprehensive Dependency Injection (DI) container that manages service instantiation, dependency resolution, and object lifecycle. The DI system eliminates manual service creation and promotes loose coupling between components.ServiceContainer Overview
TheServiceContainer is the heart of Framefox’s dependency injection system:
/home/daytona/workspace/source/framefox/core/di/service_container.py:32-64
Key Features
- Automatic Service Discovery: Scans your codebase to find and register services
- Autowiring: Resolves dependencies automatically based on type hints
- Singleton Pattern: Services are instantiated once and reused
- Tag-based Retrieval: Organize and retrieve services by tags
- Lazy Loading: Services are created only when needed
- Circular Dependency Detection: Prevents infinite dependency loops
Retrieving Services
Basic Retrieval
Get a service by its class:/home/daytona/workspace/source/framefox/core/di/service_container.py:548-566
Retrieve by Name
Get a service by its class name:/home/daytona/workspace/source/framefox/core/di/service_container.py:826-832
Retrieve by Tag
Get services associated with a specific tag:/home/daytona/workspace/source/framefox/core/di/service_container.py:834-845
/home/daytona/workspace/source/framefox/core/di/service_container.py:860-863
Automatic Dependency Injection
In Controllers
The@Route decorator automatically injects services into controller methods based on type hints:
/home/daytona/workspace/source/framefox/core/routing/decorator/route.py:27-56
The Route decorator intelligently distinguishes between:
- Services to inject: Custom services registered in the container
- FastAPI parameters: Request, Response, Query, Path, etc.
- Path parameters: URL parameters like
{user_id} - Pydantic models: Request body models
- Primitive types: int, str, bool, etc.
In Service Classes
Services can depend on other services through constructor injection:UserService from the container, its dependencies are automatically resolved:
Dependency Resolution
The container resolves dependencies using type hints:/home/daytona/workspace/source/framefox/core/di/service_container.py:672-712
Circular Dependency Detection
The container detects and prevents circular dependencies:/home/daytona/workspace/source/framefox/core/di/service_container.py:580-598
Service Registration
Automatic Discovery
Framefox automatically discovers services in your project:/home/daytona/workspace/source/framefox/core/di/service_container.py:225-258
framefox.core- Framework core servicessrc/- Your application services (excluding controllers, entities, migrations)
Manual Registration
You can manually set service instances:/home/daytona/workspace/source/framefox/core/di/service_container.py:873-876
Service Factories
Register custom factories for complex service creation:/home/daytona/workspace/source/framefox/core/di/service_container.py:878-880
Service Lifecycle
Singleton Pattern
All services in Framefox are singletons by default. Once created, the same instance is reused:Service Caching
The container implements two levels of caching:- Instance Cache: Stores created service instances
- Resolution Cache: Speeds up repeated retrievals
/home/daytona/workspace/source/framefox/core/di/service_container.py:797-809
Advanced Usage
Checking Service Existence
/home/daytona/workspace/source/framefox/core/di/service_container.py:865-871
Container Statistics
/home/daytona/workspace/source/framefox/core/di/service_container.py:908-919
Best Practices
Always Use Type Hints
Always Use Type Hints
Type hints are essential for autowiring to work:
Avoid Circular Dependencies
Avoid Circular Dependencies
Design your services to avoid circular dependencies:
Keep Services Focused
Keep Services Focused
Each service should have a single, well-defined responsibility:
Use Interfaces for Abstraction
Use Interfaces for Abstraction
Depend on interfaces rather than concrete implementations:
Troubleshooting
Service Not Found Error
If you get aServiceNotFoundError, ensure:
- The service class is in the
src/directory (not in excluded directories) - The class name follows Python naming conventions (starts with uppercase)
- The module doesn’t have import errors
Circular Dependency Error
If you encounter circular dependencies:- Review your service dependencies
- Extract shared logic into a separate service
- Consider using lazy imports or factory patterns
Type Hint Issues
If autowiring isn’t working:- Ensure you’re using proper type hints
- Check for forward reference issues
- Verify the service is registered in the container
Next Steps
MVC Pattern
See how DI integrates with controllers
Services
Learn to create custom services
Testing
Mock services for unit testing
Architecture
Understand the overall framework architecture