Container — Aquilia Documentation
Comprehensive guide and documentation for Container in the Aquilia framework. View API reference, examples, and implementation patterns.
Dependency Injection / Container DI Container The Container is the central state engine for resolved services. It manages provider lifecycle transitions, caches instances by scope, and delegates queries up hierarchical container chains. Internal Structure The Container uses __slots__ with 8 attributes for direct memory allocation, bypassing class dictionary lookups entirely: Slot Type Purpose ))} Creating Containers from aquilia.di.core import Container # Root app container (created by Registry.build_container() internally) container = Container(scope="app") # With explicit parent (for manual hierarchies) request_container = Container(scope="request", parent=container) # Preferred: use the factory method for request scoping request_container = container.create_request_scope() # → Creates child with shared _providers (by reference), fresh _cache, # and _NullLifecycle (no-op lifecycle for lightweight request containers) Note: In production web workflows, you almost never create containers manually. The Registry.build_container() method builds the root container, and the ASGI server middleware executes create_request_scope() on every incoming request automatically. API Reference register(provider, *, tag=None) Register a Provider instance. Raises on duplicate token+tag combinations. from aquilia.di import ClassProvider provider = ClassProvider(UserService, scope="request") container.register(provider) # With a tag for disambiguation container.register(redis_provider, tag="redis") bind(interface, implementation, *, scope="app", tag=None) Bind an interface type to a concrete implementation. Creates a ClassProvider internally. from abc import ABC, abstractmethod from aquilia.controller import Controller, get class IUserRepo(ABC): @abstractmethod async def find(self, id: str): ... class PostgresUserRepo(IUserRepo): def __init__(self, pool: DatabasePool): self.pool = pool async def find(self, id: str): return await self.pool.fetch_one("SELECT * FROM users WHERE id=$1", id) # Bind interface → implementation container.bind(IUserRepo, PostgresUserRepo, scope="app") # Web Controllers resolve this automatically via constructor injection: class UserController(Controller): prefix = "/users" def __init__(self, repo: IUserRepo): # Resolved to PostgresUserRepo self.repo = repo @get("/ ") async def get_user(self, ctx): user = await self.repo.find(ctx.request.params["id"]) return ctx.json(user) resolve_async(token, *, tag=None, optional=False) Primary async resolution path. Optimized for <3µs cached lookups with O(1) cache check and parent container delegation. # Standard resolution user_svc = await container.resolve_async(UserService) # Tagged resolution redis = await container.resolve_async(CacheBackend, tag="redis") create_request_scope() Create a lightweight child container for request-scoped isolation. The child shares the parent's providers but has isolated caches and finalizers. shutdown() Drains finalizers in LIFO order (clean up database connections or file handlers), runs lifecycle shutdown hooks, and clears the instance cache. Caching Behavior by Scope Scope Cached? Where Cached Behavior ))} DI Overview Providers )
Go to Homepage