Skip to content

What is the proper way to handle dependencies at module load time? #677

Open
@cpvandehey

Description

@cpvandehey

Hello all! Im having a fun time experimenting with this framework, but have found myself stumped on this design issue for a while. In short, if a dependency needs to be used at module load time (e.g. decorators), the init_resources/wiring breaks

Example

containers.py

class ApplicationContainer(containers.DeclarativeContainer):
    my_dependency = providers.Singleton(myClass)
    my_decorator = providers.Callable(my_dynamic_decorator_function, my_dependency)

main.py

application_container = dependency_containers.ApplicationContainer()
application_container.init_resources()
application_container.wire(modules=module_names, packages=packages)

some_dangerous_file.py

from . import containers

@containers.ApplicationContainer.my_decorator()
def my_function():
  print("...")

dependency_injector.errors.Error: Can not copy initialized resource

This is notably caused by the way/order python loads modules. All decorators are applied before the AppContainer or main can properly wire/initialize the dependencies. This basically means that if there is a dependency that is used outside a function, it will fail.

Is there any design or trick to get around this, i'd love to hear it. I don't like the idea of putting any container initialization into the dunder init file.

Here are some of my thoughts:
If there was a dependency/provider type that wraps a dependency that doesn't need to be available immediately i.e. lazy initialization, the module load would work at bootup and would be properly injected when it needs to be (after main executes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions