Python Dependency Injection Framework
A lightweight, type-safe dependency injection framework for Python that supports singleton, lazy singleton, and factory registrations, with scoped overrides and flexible parameter injection.
Features
- Registry-based DI: Register services and resolve them by type and optional tags.
- Scoped overrides: Create temporary overrides using context managers.
- Injection decorator: Automatically inject dependencies into functions, methods, or constructors.
- Multiple registration modes:
SINGLETON: Single instance shared globally.LAZY_SINGLETON: Created on first access and then cached.FACTORY: New instance created on every resolution.
- Tag-based resolution: Support multiple implementations of the same interface.
- Type-safe: Uses Python type annotations for automatic injection.
- Supports instance, class, and static methods.
Usage
Using the Global Locator
The package provides a pre-created global locator available from the module:
from di import locator, inject, RegistrationMode, NotRegisteredError
You can register services directly in the global locator:
from di import locator, RegistrationMode
class Service:
pass
locator.register(Service, lambda: Service(), RegistrationMode.SINGLETON)
locator.register(int, lambda: 42, RegistrationMode.SINGLETON, tag="answer")
Resolve dependencies manually:
service_instance = locator.resolve(Service)
number = locator.resolve(int, tag="answer")
Function and Method Injection with the Global Locator
from di import locator, inject
@inject(locator, params=["service", "num:answer"])
def process(service: Service, num: int):
return service, num
s, n = process()
Supports injection into:
-
Instance methods:
class MyClass: @inject(locator, params=["service"]) def method(self, service: Service): return service
-
Class methods:
class MyClass: @classmethod @inject(locator, params=["service"]) def method(cls, service: Service): return service, cls
-
Static methods:
class MyClass: @staticmethod @inject(locator, params=["service"]) def method(service: Service): return service
-
Constructors:
class MyClass: @inject(locator, params=["service"]) def __init__(self, service: Service): self.service = service
Scoped Overrides
with locator.override():
locator.register(Service, lambda: CustomService(), RegistrationMode.SINGLETON)
instance = locator.resolve(Service) # Returns CustomService
# Outside override, original registration restored
instance = locator.resolve(Service) # Returns Service
Registration Modes
| Mode | Behavior |
|---|---|
SINGLETON |
Single instance created at registration and reused for all resolutions. |
LAZY_SINGLETON |
Instance created on first resolution, then cached for subsequent calls. |
FACTORY |
Factory function called on every resolution to return a new instance. |
Error Handling
NotRegisteredError: Raised when a requested type or tag is not registered.RootScopeCloseError: Raised when attempting to close the root scope of aLocator.
Advanced Usage
While the global locator is sufficient for most cases, you can create custom locators or registries if you need isolated scopes or multiple independent DI containers:
from di import Locator, Registry
my_locator = Locator()
my_registry = Registry()
Metadata
Release files for pydi-framework 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydi_framework-1.0.0.tar.gz | 7.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydi_framework-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.3 kB
Release files / pydi_framework-1.0.0.tar.gz
| Download URL | pydi_framework-1.0.0.tar.gz |
|---|---|
| Size | 7.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
95b9534af93ce04416a88f852a9a8aa0af450a5cff029c5c80a23a45df99ad43
|
|
BLAKE2b-256 checksum How to use checksums |
41ba56b9728a95d0ad91f66d497c8f4710ec81e7f3b147bc704ce3f66d25a3f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 1, 2026.
Transparency logRelease files / pydi_framework-1.0.0-py3-none-any.whl
| Download URL | pydi_framework-1.0.0-py3-none-any.whl |
|---|---|
| Size | 6.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0fb2ae55e97d6763ab5eb70e9483e03f89ce363fc42009809aa6e26d76dee803
|
|
BLAKE2b-256 checksum How to use checksums |
a8e4625882ed06b4a65157fa3b0a8001c8810f234022eac8a399ec80aff5889e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 1, 2026.
Transparency log