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-0.2.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-0.2.0-py3-none-any.whl
(13.6 kB
view details)
File details
Details for the file qx_di-0.2.0.tar.gz.
File metadata
- Download URL: qx_di-0.2.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2d05ec1ac7b5f809d94d894bfde42fd258dc8ccb1f298b7c569dbf9e471a977
|
|
| MD5 |
ca228cc908d2df3f3d52f94b0506dad5
|
|
| BLAKE2b-256 |
18b24e72429114021f553175cc46570ece4a59c62d7a1b4552079cbfc1f106fa
|
File details
Details for the file qx_di-0.2.0-py3-none-any.whl.
File metadata
- Download URL: qx_di-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7dada278e57674a6acd6f9892e12f66c489bf64873831786053ab674a874c114
|
|
| MD5 |
016b6c3e836f9cea8545ec88f8f688d1
|
|
| BLAKE2b-256 |
6ffd242c434e2d54f97a01b427ef232c23daad046a6d837276c3056671c6c7bf
|