String Injection
Provider resolution by name¶
The @inject decorator can be used to inject a provider by its name. This is useful when you want to inject a provider that is not directly imported in the current module.
This serves two primary purposes:
- A higher level of decoupling between container and your code.
- Avoiding circular imports.
Usage¶
To inject a provider by name, use the Provide marker with a string argument that has the following format:
The string will be validated when it is passed to Provide[], thus will raise an exception
immediately.
For example:
from that_depends import BaseContainer, inject, Provide
class Config(BaseSettings):
name: str = "Damian"
class A(BaseContainer):
b = providers.Factory(Config)
@inject
def read(val = Provide["A.b.name"]):
return val
assert read() == "Damian"
Container alias¶
Containers support aliases:
class A(BaseContainer):
alias = "C" # replaces the container name.
b = providers.Factory(Config)
@inject
def read(val = Provide["C.b.name"]): # `A` can no longer be used.
return val
assert read() == "Damian"
Considerations¶
This feature is primarily intended as a fallback when other options are not optimal or simply not available, thus is recommended to be used sparingly.
If you do decide to use injection by name, consider the following:
- In order for this type of injection to work, your container must be in scope when the injected function is called:
- Validation of whether you have provided a correct container name and provider name will only happen when the function is called.