Simple Inject
中文 README
Simple Inject is a lightweight Python dependency injection library. It provides an easy-to-use interface for managing dependencies across different namespaces and scopes.
Features
- Simple and intuitive dependency injection API
- Supports multiple namespaces to isolate dependencies
- Implements scoped dependencies using context managers or decorators
- Supports nested scopes for fine-grained control
- Supports automatic dependency injection through parameters
- Easy integration with existing projects
- Minimal overhead and dependencies
Installation
You can install Simple Inject using pip:
pip install py-simple-inject
Quick Start
Basic Usage
Here is a simple example demonstrating basic dependency injection and scope management:
from simple_inject import provide, inject, create_scope
provide('config', {'debug': True})
config = inject('config')
print(config['debug'])
Using Namespaces
from simple_inject import provide, inject, create_scope
provide('key', 'value1', namespace='ns1')
provide('key', 'value2', namespace='ns2')
print(inject('key', namespace='ns1'))
print(inject('key', namespace='ns2'))
Using Scopes
provide('config', {'debug': True})
with create_scope():
provide('config', {'debug': False})
config = inject('config')
print(config['debug'])
config = inject('config')
print(config['debug'])
Scopes can also be used with the scoped
decorator:
@scoped()
def scoped_function():
provide('key', 'scoped_value')
return inject('key')
provide('key', 'outer_value')
print(inject('key'))
print(scoped_function())
print(inject('key'))
Nested Scopes
Scoped scopes can be nested, and dependencies in inner scopes will override those in outer scopes.
provide('key', 'outer')
with create_scope():
provide('key', 'inner')
print(inject('key'))
with create_scope() as inner_scope:
provide('key', 'innermost')
print(inject('key'))
print(inject('key'))
print(inject('key'))
Accessing Scoped State
You can access the state of dependencies within a scope after it exits using the scoped_state
method:
provide('config', {'debug': True})
with create_scope() as scope:
provide('config', {'debug': False})
provide('new_setting', 'scoped_value')
provided_state = scope.scoped_state('Provided')
print(provided_state)
all_state = scope.scoped_state('All')
print(all_state)
with create_scope() as scope:
provide('key1', 'value1', namespace='ns1')
provide('key2', 'value2', namespace='ns2')
ns1_state = scope.scoped_state('Provided', 'ns1')
print(ns1_state)
The scoped_state
method supports two policies:
'Provided'
(default): Returns only dependencies that were added or modified within the scope
'All'
: Returns the complete state within the scope
Automatic Injection via Function Parameters
Simple Inject also supports automatic injection via function parameters. The following example demonstrates how to use this advanced feature:
from simple_inject import provide, inject, create_scope, auto_inject, Inject
class Engine:
def start(self):
print("Engine started")
provide('engine', Engine())
engine = inject('engine')
engine.start()
@auto_inject()
def drive(car: str, engine: Engine = Inject('engine')):
print(f"Driving {car}")
engine.start()
drive("Tesla")
with create_scope():
provide('engine', Engine())
drive("BMW")
drive("Toyota")
API Reference
provide(key: str, value: Any, namespace: str = 'default')
Provides a dependency in the current context.
inject(key: str, namespace: str = 'default') -> Any
Injects a dependency from the current context.
create_scope()
Creates a new dependency scope. Used with the with
statement.
scoped()
Decorator to create a new dependency scope for a function.
auto_inject()
Decorator to automatically inject parameters marked with Inject
.
Inject(key: str, namespace: str = 'default')
Class to mark a parameter for automatic injection.
purge(namespace: Optional[str] = None)
Clears dependencies, either for a specific namespace or for all namespaces.
Contributing
Contributions are welcome! Feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.