-
-
Notifications
You must be signed in to change notification settings - Fork 322
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
provider.Callable not working when being passed to another provider in a Container #704
Comments
If u use providers.Callable and the whole wiring machinery, said callable will be called upon injecting ur service, consider: from dependency_injector import containers, providers
from dependency_injector.wiring import Provide
def some_callable(configurable_parameter, input_value):
return configurable_parameter + input_value
class Service:
def __init__(self, callback):
self.some_callable = callback
def greet(self):
return self.some_callable(input_value=" world")
class AppContainer(containers.DeclarativeContainer):
callable_instance = providers.Callable(
some_callable, configurable_parameter="hello", input_value="_world"
)
service = providers.Singleton(Service, callback=callable_instance)
service: Service = Provide["service"]
container = AppContainer()
container.wire(modules=[__name__])
print(service.some_callable) trace:
AFAIK if u want to pass the callable isntance further down the providers chain u have to pass callable.provider property like this: def some_callable(configurable_parameter, input_value):
return configurable_parameter + input_value
class Service:
def __init__(self, callback):
self.some_callable = callback
def greet(self):
return self.some_callable(input_value=" world")
class AppContainer(containers.DeclarativeContainer):
callable_instance = providers.Callable(
some_callable, configurable_parameter="hello"
)
service = providers.Singleton(Service, callback=callable_instance.provider)
service: Service = Provide["service"]
container = AppContainer()
container.wire(modules=[__name__])
print(service.some_callable)
print(service.greet())
|
Thanks! It works and then it is used as
which suggests it should work as I initially tried. It completely flew over my head that indeed I will try to update the documentation to have this example. |
Hi,
I've encountered a problem in our project with Callable providers and nailed the problem down to this scenario.
Namely, when we have a Factory and we want to use it in another Factory, we can do it easily as such:
Doing something similar with Callable provider fails in runtime with
TypeError: some_callable() missing 1 required positional argument: 'input_value'
. Full code that causes errors is pasted below.Code is run as
python ./main.py
and then enteringlocalhost:8888
in the browser.Pip freeze output:
As you can see, I want to use below code:
It fails with that dependency-injector trace:
When I replace
providers.Callable
withfunctools.partial
it works, but it is definitely not what I want, as this is just a simple example and in real project it can get more complicated, with Callable being provided with different dependencies etc. I useSingleton
here, but it might as well be aFactory
or other provider.In the scenario when I need to reuse Callable in the container and provide it with some dependencies, it does not work (as per above error), I cannot use funtools.partial (as it cannot be injected with dependencies), and need to convert the function that I want to be provided to a class that just implements a single method, only for it to possible to use
providers.Factory
instead ofproviders.Callable
, which I find being a huge antipattern.I am sure though I am missing something and would love some direction
How can I make it work?
Thanks
The text was updated successfully, but these errors were encountered: