Description
I am trying to implement a behavior that is really close to ThreadLocalSingleton scopes.
I have a container that is created when app starts. It holds data about the current customer.
So when the app starts, the value is None
.
But at runtime, I want to forbid any injection if the current value is None.
Of course, I would like to keep this DI logic near containers.
(No if not context: ...
in MyService
below)
I am currently able to do this kind of tricks by having 2 providers like below.
my_context
will be overrode within each requests.
_safe_my_context
will validate it before being injected in other components.
I'm not 100% comfortable with this.
I am feeling like there's room for a DelegatedThreadLocalSingleton
that could accept MyContext | None
but would provide only a MyContext
. Just didn't find examples of Delegate...
of how to implement it properly.
Thanks for the lib!
# app/my_context.py
@dataclass
class MyContext:
customer_id: str
# app/my_service.py
class MyService:
def __init__(self, context: MyContext):
...
# app/containers.py
def _default_context() -> MyContext | None:
return None
def _ensure_context(context: MyContext | None) -> MyContext:
if context is None:
msg = "Context not set"
raise ValueError(msg)
return context
class MyContainer(containers.DeclarativeContainer):
my_context = providers.ThreadLocalSingleton(_default_context)
_safe_my_context = providers.Callable(_ensure_context, context=my_context)
some_service = providers.Factory(MyService, _safe_my_context)