Open
Description
Trying to understand how to correctly inject dependencies into a class constructor, the following is a sandbox example where I've extracted the key parts from a broader project.
from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject
class Config():
def __init__(self, config_file: str = None):
self.config_file = config_file
class Container(containers.DeclarativeContainer):
config = providers.Singleton(Config)
class Engine():
@inject
def __init__(
self,
config: Config = Provide[Container.config],
):
self.config = config
def init(self) -> None:
print(f'Reading from config: {self.config.config_file}')
def container_factory(config_file: str = None) -> Container:
container = containers.DynamicContainer()
config_provider = providers.Factory(Config, config_file=config_file) \
if config_file else providers.Factory(Config)
container.config = config_provider
return container
def main():
container = container_factory('/tmp/config.yml')
container.wire(modules=[__name__])
engine = Engine()
engine.init()
if __name__ == '__main__':
main()
I'm getting an error here from the init log:
AttributeError: 'Provide' object has no attribute 'config_file'
My expected behavior is that config
is an instance of the Config class that has been passed the config_file
value in its constructor. Instead I seem to be given an instance of the Provide class?
I have a few questions about this:
- The documentation is very vague about what wire actually does, and what it expects for its modules/packages arguments. What should these values be? The module and/or package that needs to have dependencies injected?
- I'm assuming the problem here is that the wire has failed so it's unable to inject correctly?
- I'm having a hard time finding examples that demonstrate where the
@inject
decorator needs to go for a class -- is it on the class declaration or on the actual__init__
def, if I wish to inject into the constructor?
If it's relevant, I use virtualenv .venv
to create a virtual env at the root of the project and am using poetry install
and poetry shell
to load the environment and run it.
Metadata
Metadata
Assignees
Labels
No labels