Question: Singleton initialization
See original GitHub issueI’m curious if this is allowed re: best practice (it works, which is great for me, but I’d like to know how foolish it is)
So I have a case where I have some drivers for services. One of my drivers needs another service:
class Foundation(containers.DeclarativeContainer):
http_service = providers.Singleton(
HttpService, timeout=6.05
) # type: Callable[[], HttpService]
class Drivers(containers.DeclarativeContainer):
api_driver = providers.Singleton(
ProductionAPIDriver,
api_access_key='',
cache_duration_seconds=600,
http_service=Foundation.http_service
) # type: Callable[[], ProductionAPIDriver]
data_driver = providers.Singleton(
# --- !!! > RIGHT HERE < !!! ---
# This Driver needs to be initialized with a service
# The service in question needs to be initialized with
# the driver defined above
lambda: DataDriver(Services.api_service())
# --- ^^^ > RIGHT HERE < ^^^ ---
) # type: Callable[[], APIDataDriver]
class Services:
api_service = providers.Singleton(
APIService,
driver=Drivers.api_driver
) # type: Callable[[], APIService]
data_service = providers.Singleton(
DataService,
driver=Drivers.data_driver
) # type: Callable[[], DataService]
So when I need Services.data_service
that needs to go getDrivers.data_driver
. Drivers.data_driver
needs to be initialized with a Services.api_service
. Because Drivers.data_driver
needs to itself be initialized with a service, I can’t reference the Services
at that moment in time, as it’s declared below Drivers
. To work around that, I have wrapped the Singleton
initialization in a lambda
. This allows it to run successfully since the Services
name binding inside the lambda
is effectively deferred until runtime.
So this is a bit of a hopscotch around but it does work. Now aside from making the flow more difficult to understand from a maintenance perspective, all the bouncing around, are there any other downsides to this approach?
The docs for the Singleton provider state:
Singleton
provider creates new instance of specified class (emphasis mine) on first call and returns same instance on every next call.
Of specific note is of specified class. In my case above, the specificed class is a callable in the form of a lambda. Is it safe to assume the docs really just mean of specified CALLABLE?
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
Yeah, you’re right.
In your example, you would need to use
Dependency
provider forAppContainer.app
&ServiceContainer.service
like you do now forvalue
, or youDependenciesContainer
provider - http://python-dependency-injector.ets-labs.org/examples/use_cases_miniapp.html.So, as I understood this code is valid
and this happens because of this
Correct me if I’m wrong