Annotations
WireUp relies on various kind of type annotations or hints to be able to autowire dependencies. When it is not possible to automatically locate a given dependency the argument must be annotated with additional metadata.
When do you need to provide annotations.
Optional when injecting:
- Services
- Injecting an interface which has only one implementing service
Required when injecting:
- Parameters
- Parameter expressions
- Injecting an interface which has multiple implementing services.
Annotation types
Wireup supports two types of annotations. Using Python's Annotated
or by using default values.
Annotated
This is the preferred method for Python 3.9+ and moving forward. It is also recommended to
backport this using typing_extensions
for Python 3.8.
@container.autowire
def target(
env: Annotated[str, Wire(param="env_name")],
logs_cache_dir: Annotated[str, Wire(expr="${cache_dir}/logs")],
):
...
Default values
This relies on the use of default values to inject parameters. Anything that can be passed to Annotated
may also
be used here.
@container.autowire
def target(
env: str = wire(param="env_name"),
logs_cache_dir: str = wire(expr="${cache_dir}/logs")
):
...
Explicit injection annotation
Even though annotating services is optional, you CAN still annotate them to be explicit about what will be injected. This also has the benefit of making the container throw when such as service does not exist instead of silently skipping this parameter.
@container.autowire
def target(random_service: Annotated[RandomService, Wire()]):
...