mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-01-30 19:24:31 +03:00
Update singleton provider docs, including API, and examples
This commit is contained in:
parent
fb6deaec96
commit
61e6f2db60
|
@ -268,9 +268,15 @@ class Factory(Provider):
|
|||
|
||||
|
||||
class Singleton(Provider):
|
||||
"""Singleton provider.
|
||||
""":py:class:`Singleton` provider returns same instance on every call.
|
||||
|
||||
Singleton provider will create instance once and return it on every call.
|
||||
:py:class:`Singleton` provider creates instance once and return it on every
|
||||
call. :py:class:`Singleton` uses :py:class:`Factory` for creation of
|
||||
instance, so, please follow :py:class:`Factory` documentation to go inside
|
||||
with injections syntax.
|
||||
|
||||
:py:class:`Singleton` is thread-safe and could be used in multithreading
|
||||
environment without any negative impact.
|
||||
"""
|
||||
|
||||
__slots__ = ('instance', 'factory')
|
||||
|
@ -278,25 +284,90 @@ class Singleton(Provider):
|
|||
def __init__(self, provides, *args, **kwargs):
|
||||
"""Initializer."""
|
||||
self.instance = None
|
||||
"""Read-only reference to singleton's instance.
|
||||
|
||||
:type: object
|
||||
"""
|
||||
|
||||
self.factory = Factory(provides, *args, **kwargs)
|
||||
"""Singleton's factory object.
|
||||
|
||||
:type: :py:class:`Factory`
|
||||
"""
|
||||
|
||||
super(Singleton, self).__init__()
|
||||
|
||||
@property
|
||||
def provides(self):
|
||||
"""Class or other callable that provides object for creation.
|
||||
|
||||
:type: type | callable
|
||||
"""
|
||||
return self.factory.provides
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
"""Tuple of positional argument injections.
|
||||
|
||||
:type: tuple[:py:class:`dependency_injector.injections.Arg`]
|
||||
"""
|
||||
return self.factory.args
|
||||
|
||||
@property
|
||||
def kwargs(self):
|
||||
"""Tuple of keyword argument injections.
|
||||
|
||||
:type: tuple[:py:class:`dependency_injector.injections.KwArg`]
|
||||
"""
|
||||
return self.factory.kwargs
|
||||
|
||||
@property
|
||||
def attributes(self):
|
||||
"""Tuple of attribute injections.
|
||||
|
||||
:type: tuple[:py:class:`dependency_injector.injections.Attribute`]
|
||||
"""
|
||||
return self.factory.attributes
|
||||
|
||||
@property
|
||||
def methods(self):
|
||||
"""Tuple of method injections.
|
||||
|
||||
:type: tuple[:py:class:`dependency_injector.injections.Method`]
|
||||
"""
|
||||
return self.factory.methods
|
||||
|
||||
@property
|
||||
def injections(self):
|
||||
"""Read-only tuple of all injections.
|
||||
|
||||
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
||||
"""
|
||||
return self.factory.injections
|
||||
|
||||
def reset(self):
|
||||
"""Reset cached instance, if any.
|
||||
|
||||
:rtype: None
|
||||
"""
|
||||
self.instance = None
|
||||
|
||||
def _provide(self, *args, **kwargs):
|
||||
"""Return provided instance."""
|
||||
"""Return provided instance.
|
||||
|
||||
:param args: tuple of context positional arguments
|
||||
:type args: tuple[object]
|
||||
|
||||
:param kwargs: dictionary of context keyword arguments
|
||||
:type kwargs: dict[str, object]
|
||||
|
||||
:rtype: object
|
||||
"""
|
||||
with GLOBAL_LOCK:
|
||||
if not self.instance:
|
||||
self.instance = self.factory(*args, **kwargs)
|
||||
return self.instance
|
||||
|
||||
def reset(self):
|
||||
"""Reset instance."""
|
||||
self.instance = None
|
||||
|
||||
@property
|
||||
def injections(self):
|
||||
"""Return tuple of all injections."""
|
||||
return self.factory.injections
|
||||
|
||||
|
||||
class ExternalDependency(Provider):
|
||||
"""External dependency provider.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 25 KiB |
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 26 KiB |
|
@ -1,8 +1,10 @@
|
|||
Singleton providers
|
||||
-------------------
|
||||
|
||||
``di.Singleton`` provider creates new instance of specified class on first call
|
||||
and returns same instance on every next call.
|
||||
.. module:: dependency_injector.providers
|
||||
|
||||
:py:class:`Singleton` provider creates new instance of specified class on
|
||||
first call and returns same instance on every next call.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -16,9 +18,9 @@ Example:
|
|||
Singleton providers and injections
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``di.Singleton`` providers use ``di.Factory`` providers for first creation of
|
||||
specified class instance, so, all of the rules about injections are the same,
|
||||
as for ``di.Factory`` providers.
|
||||
:py:class:`Singleton` providers use :py:class:`Factory` providers for first
|
||||
creation of specified class instance, so, all of the rules about injections
|
||||
are the same, as for :py:class:`Factory` providers.
|
||||
|
||||
.. image:: /images/providers/singleton_internals.png
|
||||
:width: 80%
|
||||
|
@ -26,29 +28,29 @@ as for ``di.Factory`` providers.
|
|||
|
||||
.. note::
|
||||
|
||||
Due that ``di.Singleton`` provider creates specified class instance only on
|
||||
the first call, all injections are done once, during the first call, also.
|
||||
Every next call, while instance has been already created and memorized, no
|
||||
injections are done, ``di.Singleton`` provider just returns memorized
|
||||
earlier instance.
|
||||
Due that :py:class:`Singleton` provider creates specified class instance
|
||||
only on the first call, all injections are done once, during the first
|
||||
call, also. Every next call, while instance has been already created
|
||||
and memorized, no injections are done, :py:class:`Singleton` provider just
|
||||
returns memorized earlier instance.
|
||||
|
||||
This may cause some problems, for example, in case of trying to bind
|
||||
``di.Factory`` provider with ``di.Singleton`` provider (provided by
|
||||
dependent ``di.Factory`` instance will be injected only once, during the
|
||||
first call). Be aware that such behaviour was made with opened eyes and is
|
||||
not a bug.
|
||||
:py:class:`Factory` provider with :py:class:`Singleton` provider (provided
|
||||
by dependent :py:class:`Factory` instance will be injected only once,
|
||||
during the first call). Be aware that such behaviour was made with opened
|
||||
eyes and is not a bug.
|
||||
|
||||
By the way, in such case, ``di.Delegate`` provider can be useful. It makes
|
||||
possible to inject providers *as is*. Please check out full example in
|
||||
*Providers delegation* section.
|
||||
By the way, in such case, :py:class:`Delegate` provider can be useful. It
|
||||
makes possible to inject providers *as is*. Please check out full example
|
||||
in *Providers delegation* section.
|
||||
|
||||
Singleton providers resetting
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Created and memorized by ``di.Singleton`` instance can be reset. Reset of
|
||||
``di.Singleton``'s memorized instance is done by clearing reference to it.
|
||||
Further lifecycle of memorized instance is out of ``di.Singleton`` provider's
|
||||
control.
|
||||
Created and memorized by :py:class:`Singleton` instance can be reset. Reset of
|
||||
:py:class:`Singleton`'s memorized instance is done by clearing reference to
|
||||
it. Further lifecycle of memorized instance is out of :py:class:`Singleton`
|
||||
provider's control.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -58,13 +60,13 @@ Example:
|
|||
Singleton providers delegation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``di.Singleton`` provider could be delegated to any other provider via any
|
||||
kind of injection. Delegation of ``di.Singleton`` providers is the same as
|
||||
``di.Factory`` providers delegation, please follow
|
||||
*Factory providers delegation* section for example.
|
||||
:py:class:`Singleton` provider could be delegated to any other provider via
|
||||
any kind of injection. Delegation of :py:class:`Singleton` providers is the
|
||||
same as :py:class:`Factory` providers delegation, please follow *Factory
|
||||
providers delegation* section for example.
|
||||
|
||||
``di.Singleton`` delegate could be created obviously using
|
||||
``di.Delegate(di.Singleton())`` or by calling ``di.Singleton.delegate()``
|
||||
:py:class:`Singleton` delegate could be created obviously using
|
||||
``Delegate(Singleton(...))`` or by calling ``Singleton(...).delegate()``
|
||||
method.
|
||||
|
||||
Example:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""`di.Singleton` providers example."""
|
||||
"""`Singleton` providers example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class UserService(object):
|
||||
|
@ -8,7 +8,7 @@ class UserService(object):
|
|||
|
||||
# Singleton provider creates new instance of specified class on first call and
|
||||
# returns same instance on every next call.
|
||||
users_service_provider = di.Singleton(UserService)
|
||||
users_service_provider = providers.Singleton(UserService)
|
||||
|
||||
# Retrieving several UserService objects:
|
||||
user_service1 = users_service_provider()
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"""`di.Singleton` providers delegation example."""
|
||||
"""`Singleton` providers delegation example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
# Some singleton provider and few delegates of it:
|
||||
singleton_provider = di.Singleton(object)
|
||||
singleton_provider = providers.Singleton(object)
|
||||
singleton_provider_delegate1 = singleton_provider.delegate()
|
||||
singleton_provider_delegate2 = di.Delegate(singleton_provider)
|
||||
singleton_provider_delegate2 = providers.Delegate(singleton_provider)
|
||||
|
||||
# Making some asserts:
|
||||
assert singleton_provider_delegate1() is singleton_provider
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
"""`di.Singleton` providers resetting example."""
|
||||
"""`Singleton` providers resetting example."""
|
||||
|
||||
import dependency_injector as di
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class UserService(object):
|
||||
"""Example class UserService."""
|
||||
|
||||
# Users service singleton provider:
|
||||
users_service_provider = di.Singleton(UserService)
|
||||
users_service_provider = providers.Singleton(UserService)
|
||||
|
||||
# Retrieving several UserService objects:
|
||||
user_service1 = users_service_provider()
|
||||
|
|
Loading…
Reference in New Issue
Block a user