-
-
Couldn't load subscription status.
- Fork 339
Description
Hello! I encountered with a problem, which can not solve about 3 days. This is due to the nested di containers provided by providers. Container or providers.DependenciesContainer. The main problem that I can not understand how to use it, or the lib does not work as expected. Here is a short example.
from __future__ import annotations
from datetime import tzinfo
from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject
from pytz import timezone
class Clock:
def __init__(self, tz: tzinfo): self.tz = tz
class Repository: ...
class CommandHandler:
def __init__(self, clock: Clock, repo): self.clock, self.repo = clock, repo
# Core
class CoreServicesDIContainer(containers.DeclarativeContainer):
clock = providers.Singleton(Clock, tz=timezone("Asia/Dushanbe"))
class CoreDIContainer(containers.DeclarativeContainer):
services = providers.DependenciesContainer()
handler = providers.Singleton(
CommandHandler,
clock=services.clock,
repo=lambda: 1,
)
# Application
class ApplicationRepositoryDIContainer(containers.DeclarativeContainer):
some_repository = providers.Factory(Repository)
class ApplicationHandlersDIContainer(containers.DeclarativeContainer):
core = providers.DependenciesContainer()
repositories = providers.DependenciesContainer()
command_handler = providers.Factory(
CommandHandler,
clock=core.provided.services.clock,
repo=repositories.some_repository,
)
class ApplicationDIContainer(containers.DeclarativeContainer):
core = providers.DependenciesContainer()
repositories = providers.Container(ApplicationRepositoryDIContainer)
handlers = providers.Container(ApplicationHandlersDIContainer, core=core, repositories=repositories)
# Root
class RootDIContainer(containers.DeclarativeContainer):
core = providers.Container(CoreDIContainer, services=providers.Container(CoreServicesDIContainer))
application = providers.Container(ApplicationDIContainer, core=core)
@inject
def handle(handler: CommandHandler = Provide["application.handlers.command_handler"]): # If replace to "core.services.clock", 'Clock' instance will return.
print("OK:", type(handler.clock), type(handler.repo))
def main():
root = RootDIContainer()
root.wire(modules=[__name__])
handle()
if __name__ == "__main__":
main()The result:
OK: <class 'dependency_injector.providers.Dependency'> <class '__main__.Repository'>
If execute script above, the clock type given to handler is 'provider.Singleton'. I noticed that when I address two nested containers at once, like I declared command_handler inside of ApplicationHandlersDIContainer, it will return a provider object instead of dependency object. But repository injection works correct as expected. So, I think the problem in nested containers dependency. Also, provided prop is not helping here. I tried each way.
If you encountered any problem like this, help please. Thank you in advance.