Static, lazily-resolved declarative DI containers built on dependency-injector.
Project description
static-dependency-injector
Static, lazily-resolved declarative DI containers built on top of
dependency-injector.
Declare providers as class attributes and read them back as resolved values
straight from the container class — no instance, no () call:
from static_dependency_injector import static_providers as sp
from static_dependency_injector.containers import StaticDeclarativeContainer
class Services(StaticDeclarativeContainer):
config = sp.Singleton(load_config)
db = sp.Singleton(Database, config=config)
db = Services.db # resolved Database instance (lazy, cached)
Services.set_overrides(db=fake_db) # override (e.g. in a test)
Services.clear_overrides("db") # clear it (or clear_overrides() for all)
Providers stay lazy: the underlying callables are not invoked until first access,
and each provider keeps dependency-injector's caching semantics.
Installation
pip install static-dependency-injector
# or
uv add static-dependency-injector
Why
- Read providers as values —
Services.dbreturns the resolved instance, no()call and no container instance. - Fully typed — reads resolve to the dependency's type, and the override API is clean under ty, mypy and pyright (Pylance).
- Lazy & cached — keeps
dependency-injector's resolution and per-provider caching semantics; nothing is built until first access. - Test-friendly —
set_overrides/clear_overridesfor per-test overrides, plusTestContextSingletonauto-reset via a bundled pytest plugin. - Thin — a typed wrapper over
dependency-injector; no vendoring, no magic beyond the container metaclass.
Providers
Typed wrappers over dependency-injector providers (static_providers):
Factory, Singleton, ThreadSafeSingleton, ThreadLocalSingleton,
ContextLocalSingleton, Callable, Coroutine, Object, Resource,
Dependency, Selector, Provider, and the test-scoped TestContextSingleton.
Each is generic in its resolved type, so Services.db reads back as the
dependency's type.
Test-scoped providers
TestContextSingleton is reset automatically after every test by the bundled
pytest plugin (auto-registered on install) — no manual reset() in teardown:
class Services(StaticDeclarativeContainer):
driver = sp.TestContextSingleton(make_driver)
# after each test the plugin calls Services.reset_test_context() for you
You can also reset manually: Services.reset_test_context().
Type checking
Reads resolve to the dependency's type, and the override API type-checks clean
under ty, mypy and pyright (Pylance) — verified by a test matrix that
runs all three. Overriding is done with set_overrides / clear_overrides;
direct attribute assignment (Services.db = …) is intentionally rejected by all
three checkers, so there is one obvious, typed way to override.
Notes & limitations
Because containers are resolved at the class level (no container instance):
- Overrides go through
set_overrides/clear_overrides. dependency_injector's container-level override (Container.override(other_container)) does not affect resolution here - reads come from the static registry, not a container instance. Resourceteardown is not triggered automatically: aResourceprovider initializes on first access, but its post-yieldteardown needs a container instance /shutdown_resources(), which the class-level model does not drive. UseResourcefor init-only setup, or manage teardown yourself.
Requirements
- Python 3.12+ (uses PEP 695 generics)
dependency-injector >= 4.49.1
License
MIT. Uses dependency-injector (BSD-3-Clause) as a runtime dependency; none of
its source is vendored.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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
File details
Details for the file static_dependency_injector-0.2.0.tar.gz.
File metadata
- Download URL: static_dependency_injector-0.2.0.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Artix Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ef1d138972756d6110a7beb651abbe12a0a528bfc9db8a2f4f72c68a10ace91
|
|
| MD5 |
383f8bff956a6836bdebd0ec8cac9024
|
|
| BLAKE2b-256 |
243a5894ce6e1ea23db4339b7c29c78989f7acc67a5e7f111ca2c76f28d62273
|
File details
Details for the file static_dependency_injector-0.2.0-py3-none-any.whl.
File metadata
- Download URL: static_dependency_injector-0.2.0-py3-none-any.whl
- Upload date:
- Size: 11.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Artix Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b528e8dca85e1aa1551d8dd87573d881bacbf11f1df42c612a11fd1a0617f97
|
|
| MD5 |
effbb8b335f6af4607c352108d3d72a4
|
|
| BLAKE2b-256 |
8fbc13187cda05e6517bd2768537bce9994f742d7e6761ed5561464dd7145ddf
|