Qx dependency-injection container: singleton/scoped/transient, async lifecycle, generic-aware resolution
Project description
qx-di
Async dependency-injection container for the Qx framework. Supports SINGLETON, SCOPED, and TRANSIENT lifetimes with full async lifecycle, generic-aware resolution, and decorator-based registration.
What lives here
qx.di.Container— resolves, caches, and scopes dependencies. Supportsregister_singleton,register_scoped,register_transient,register_instance, andoverride.qx.di.Scope— per-request child scope. Scoped registrations live exactly as long as their scope.qx.di.Lifetime—SINGLETON/SCOPED/TRANSIENTenum.qx.di.singleton/scoped/transient— class decorators that embed registration metadata without touching the class interface.qx.di.scan— discover and register all decorated classes in a package tree.qx.di.injectable— low-level decorator for explicit key/lifetime/factory overrides.
Usage
from qx.di import Container, Scope, scoped, singleton, scan
@singleton()
class Database:
def __init__(self, url: str) -> None: ...
@scoped(key=UserRepository)
class PgUserRepository(UserRepository):
def __init__(self, db: Database) -> None: ...
container = Container()
scan(container, "myapp.infrastructure")
container.register_instance(str, "postgresql+asyncpg://...")
async with container.scope() as scope:
repo = await container.resolve(UserRepository, scope=scope)
Design rules
- Annotation-driven —
_call_factoryinspectsget_type_hints()to resolve constructor parameters. No manual wiring for the common case. - Scope propagation — pass the active
Scopeintomediator.send()and it threads through all transient factory resolutions so thatSCOPEDdependencies (e.g.UnitOfWork) are reachable from handlers. - Cycle detection — circular dependencies raise
ResolutionErrorat first resolution, not at registration time. - Override —
container.override(key, instance)replaces any registration; used in tests to swap real infrastructure for fakes. - No reflection at module-import time.
scan()defers all class inspection to the firstresolve()call.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
qx_di-1.1.0.tar.gz
(12.6 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
qx_di-1.1.0-py3-none-any.whl
(13.6 kB
view details)
File details
Details for the file qx_di-1.1.0.tar.gz.
File metadata
- Download URL: qx_di-1.1.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7df4b3a6b64fc5dca00c10074fee383398eabccf93f2d7ca61e83ca03f00412c
|
|
| MD5 |
ff9a1b7e470857978923ce794fe0db7a
|
|
| BLAKE2b-256 |
d613da9027e2a6004db7c5d28312e9d29ec8af7274dab93d1188e4741d3ff357
|
File details
Details for the file qx_di-1.1.0-py3-none-any.whl.
File metadata
- Download URL: qx_di-1.1.0-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f57d30ae1ffe76889011689ffa715b0b9e5f1766c0c4d70eef47861b48bce1d
|
|
| MD5 |
697728a37565e7e76480efe7c73ab6f7
|
|
| BLAKE2b-256 |
1cbf2389a0fb31aa80611aaf9be40320f2c5187900a5f57ef1d473d11ead5bb8
|