Closed hf-kklein closed 2 years ago
Hi,
Everything is pretty simple:
configure
configures a global injector or raises an exception if already configured.configure_once
passes if already configured.binder.install
allows to split one config into multiple configs and compose them.clear_and_configure
should be used only in tests.In a web app I want to inject some dependencies during the startup of the application (once for the entire lifetime of the app). Other dependencies I'd like to inject using bind_to_provider but the provider is only just created at runtime because it's based on user inputs.
Configuration is static and should be specified at one point. Configuration is roughly a map between types and various providers.
def config(binder):
binder.bind(Database, PgDatabase('localhost:5432')) # will inject the same instance everywhere
binder.bind_to_provider(Cache, get_cache) # will call get_cache to get an instance every time
How can I mix both:
Everything should be specified during startup. You cannot change injector configuration after configure
call.
thanks for this super fast and helpful answer :)
To anyone having the same issue. The approach I used in the end is a ContextVar (which is imho way easier to use than the threading.local()
described in the README.
I call the following code on startup:
class MyLocalData:
# something dynamic that changes e.g. every request
class MyStaticThing:
# something of which I want to get the same instance every time
current_local_data: ContextVar[MyLocalData] = ContextVar("current_local_data")
def get_current_local_data() -> MyLocalData:
return current_local_data.get()
my_static_singleton = MyStaticThing()
inject.configure(lambda binder: binder
.bind(MyStaticThing, my_static_singleton) # <-- same for all calls
.bind_to_provider(MyLocalData, get_current_local_data)) # <-- changes with the context var
then, in my web application request handler I only need to set the context var:
def my_request_handler():
local_data : MyLocalData = ... # something from the request body... or whatever
current_local_data.set(local_data)
# do the thing that uses python-inject
Hi, I'm a bit lost when it comes to the difference between
configure
,install
andconfigure_once
. In a web app I want to inject some dependencies during the startup of the application (once for the entire lifetime of the app). Other dependencies I'd like to inject usingbind_to_provider
but the provider is only just created at runtime because it's based on user inputs.How can I mix both:
Do I have to
clear_and_configure
all bindings including those that have already been bound during startup evertime I bind something (dynamically) to the provider? A MWE would be greatly appreciated :)