Dependency Injection
AppUnit provides Dependency Injection mechanism which allows the creation of dependent objects outside of a class and provides those objects to a class through different way using Injector framework.
Bindings
You can set and get application dependencies using bind
and lookup
methods.
from appunit.applications import AppUnit
app = AppUnit()
app.bind(str, to="Hello DI!")
print(app.lookup(str))
Output:
Hello DI!
Scopes
You can also provide different scopes to your dependencies.
No Scope
from appunit.applications import AppUnit
app = AppUnit()
app.bind(str, to="Hello DI!")
print(app.lookup(str))
Singleton
Defining binding with singleton scope means the container creates a single instance of that binding, and all requests for that binding interface will return the same object, which is cached.
from injector import SingletonScope
from appunit.applications import AppUnit
class Component:
def __init__(self, name: str):
self.name = name
app = AppUnit()
app.bind(Component, to=Component("db"), scope=SingletonScope)
print(app.lookup(Component))
Request
Defining binding with request scope means the container creates a single instance of that binding for every request which is cached.
from injector import inject
from starlette.requests import Request
from appunit.applications import AppUnit
from appunit.dependencies import RequestScope
class Path(str):
pass
@inject
def get_path(request: Request) -> Path:
return Path(request.url.path)
app = AppUnit()
app.bind(Path, to=get_path, scope=RequestScope)
@app.get("/")
def index(path: Path):
return f"path is `{path}`"
if __name__ == "__main__":
app.run()
inject
decorator declaring parameters to be injected.