-
Notifications
You must be signed in to change notification settings - Fork 0
Dependency Injection
santiago edited this page Jan 29, 2026
·
1 revision
The framework provides powerful dependency injection capabilities with automatic type resolution.
The framework automatically resolves dependencies using Python type annotations. Simply declare your dependencies in the constructor:
class UserService:
def __init__(self, repository: IUserRepository, logger: ILogger):
self.repository = repository
self.logger = loggerThe container will automatically:
- Look up registered services matching the type annotations
- Resolve their dependencies recursively
- Inject them into your service
You can also manually resolve services from the container:
# Get a service
service = container.get_service(IService)
# The container returns the registered implementation
user_service = container.get_service(IUserService)If multiple implementations of the same interface are registered, get_service() returns a list:
# If multiple IStrategy implementations are registered
strategies = container.get_service(IStrategy) # Returns list[IStrategy]You can inject multiple implementations of the same interface by using list[Interface] in your constructor:
class Processor:
def __init__(self, strategies: list[IStrategy]):
self.strategies = strategies # List of all registered IStrategy implementations
def process(self, data):
for strategy in self.strategies:
strategy.execute(data)Register multiple implementations:
@register_service
def register_services(self):
self.container.add_scoped(IStrategy, lambda: StrategyA())
self.container.add_scoped(IStrategy, lambda: StrategyB())
self.container.add_scoped(IStrategy, lambda: StrategyC())
# Processor will receive all three strategies
self.container.add_scoped(Processor)- Type Annotation: The container reads type annotations from constructor parameters
- Service Lookup: It searches for registered services matching the type
- Recursive Resolution: If dependencies have their own dependencies, they're resolved recursively
- Lifetime Management: The container respects service lifetimes (Singleton, Scoped, Transient)
- Injection: Dependencies are injected into the constructor
# Register services
@register_service
def register_services(self):
self.container.add_singleton(IConfiguration, lambda: Configuration())
self.container.add_scoped(IDatabaseContext, lambda: DatabaseContext(...))
self.container.add_scoped(IUserRepository, lambda: UserRepository(
self.container.get_service(IDatabaseContext)
))
self.container.add_scoped(IUserService, lambda: UserService(
self.container.get_service(IUserRepository),
self.container.get_service(IConfiguration)
))
# Usage in controller
class UserController(BaseController):
async def get_user(self, req: func.HttpRequest):
# All dependencies are automatically resolved
user_service = self.container.get_service(IUserService)
# user_service has repository, which has database context, etc.