Context dataΒΆ
Often, your scopes are assigned with some external events: HTTP-requests, message from queue, callbacks from framework. You can use those objects when creating dependencies.
The difference from normal factories is that they are not created inside some Provider, but passed to the scope.
Working with context data consists of three parts:
- Declaration that object is received from context using from_context. You need to provide the type and scope.
For the context passed to
make_containerandmake_async_containerfunctions it is done automatically in default component.Context is shared across all providers. You do not need to specify it in each provider.
For the frameworks integrations you can use predefined providers instead of defining context data manually
To access context from additional components you need to use
from_contextis each of them in addition to default component.
Usage of that object in providers.
Passing actual values on scope entrance. It can be container creation for top level scope or container calls for nested ones. Use it in form
context={Type: value,...}.
from framework import Request
from dishka import Provider, make_container, Scope, from_context, provide
class MyProvider(Provider):
scope = Scope.REQUEST
# declare context data for nested scope
request = from_context(provides=Request, scope=Scope.REQUEST)
# use objects as usual
@provide
def a(self, request: Request, broker: Broker) -> A:
return A(data=request.contents)
# passed APP-scoped context variable is automatically available as a dependency
container = make_container(MyProvider(), context={Broker: broker})
while True:
request = broker.recv()
# provide REQUEST-scoped context variable
with container(context={Request: request}) as request_container:
a = request_container.get(A)
Note
If you are using multiple components, you need to specify from_context in them separately though the context is share.