2020-09-01 23:04:48 +03:00
|
|
|
Singleton provider
|
|
|
|
------------------
|
2015-06-10 12:00:43 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
.. meta::
|
|
|
|
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Singleton,Pattern,Example,
|
|
|
|
Threads,Multithreading,Scoped
|
|
|
|
:description: Singleton provider helps to provide a single object. This page
|
|
|
|
demonstrates how to use a Singleton provider. It also provides the example
|
|
|
|
of using a singleton and thread locals singleton in the multi-threaded
|
|
|
|
environment.
|
2015-06-10 12:00:43 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
.. currentmodule:: dependency_injector.providers
|
2015-06-24 12:29:58 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
:py:class:`Singleton` provider provides single object. It memorizes the first created object and
|
|
|
|
returns it on the rest of the calls.
|
2015-06-24 12:29:58 +03:00
|
|
|
|
2015-08-03 15:56:40 +03:00
|
|
|
.. literalinclude:: ../../examples/providers/singleton.py
|
|
|
|
:language: python
|
2020-09-01 23:04:48 +03:00
|
|
|
:lines: 3-
|
2015-06-10 12:00:43 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
``Singleton`` provider handles an injection of the dependencies the same way like a
|
|
|
|
:ref:`factory-provider`.
|
2015-06-24 12:29:58 +03:00
|
|
|
|
2015-06-10 12:00:43 +03:00
|
|
|
.. note::
|
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
``Singleton`` provider does dependencies injection only when creates the object. When the object
|
|
|
|
is created and memorized ``Singleton`` provider just returns it without applying the injections.
|
2015-06-10 12:00:43 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
Specialization of the provided type and abstract singletons work the same like like for the
|
|
|
|
factories:
|
2015-06-10 12:00:43 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
- :ref:`factory-specialize-provided-type`
|
|
|
|
- :ref:`abstract-factory`
|
2015-06-10 12:00:43 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
Resetting memorized object
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2015-07-20 19:31:31 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
To reset a memorized object you need to call the ``.reset()`` method of the ``Singleton``
|
|
|
|
provider.
|
2015-12-28 18:25:25 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
.. literalinclude:: ../../examples/providers/singleton_resetting.py
|
|
|
|
:language: python
|
|
|
|
:lines: 3-
|
|
|
|
:emphasize-lines: 14
|
2016-08-19 00:56:41 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
.. note::
|
|
|
|
Resetting of the memorized object clears the reference to it. Further object's lifecycle is
|
|
|
|
managed by the garbage collector.
|
2017-04-07 01:00:52 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
Using singleton with multiple threads
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2017-04-07 01:00:52 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
``Singleton`` provider is NOT thread-safe. You need to explicitly establish a synchronization for
|
|
|
|
using the ``Singleton`` provider in the multi-threading application. Otherwise you could trap
|
|
|
|
into the race condition problem: ``Singleton`` will create multiple objects.
|
2017-04-07 01:00:52 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
There are two thread-safe singleton implementations out of the box:
|
2016-08-19 00:56:41 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
+ :py:class:`ThreadSafeSingleton` - is a thread-safe version of a ``Singleton`` provider. You can use
|
|
|
|
in multi-threading applications without additional synchronization.
|
|
|
|
+ :py:class:`ThreadLocalSingleton` - is a singleton provider that uses thread-locals as a storage.
|
|
|
|
This type of singleton will manage multiple objects - the one object for the one thread.
|
2016-11-11 18:05:25 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
.. literalinclude:: ../../examples/providers/singleton_thread_locals.py
|
|
|
|
:language: python
|
|
|
|
:lines: 3-
|
|
|
|
:emphasize-lines: 11,12
|
2016-08-19 00:56:41 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
Implementing scopes
|
|
|
|
~~~~~~~~~~~~~~~~~~~
|
2016-08-19 00:56:41 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
To implement a scoped singleton provider use a ``Singleton`` provider and reset its scope when
|
|
|
|
needed.
|
2016-08-19 00:56:41 +03:00
|
|
|
|
2020-09-01 23:04:48 +03:00
|
|
|
.. literalinclude:: ../../examples/providers/singleton_scoped.py
|
2016-08-19 00:56:41 +03:00
|
|
|
:language: python
|
2020-09-01 23:04:48 +03:00
|
|
|
:lines: 3-
|
|
|
|
|
|
|
|
The output should look like this (each request a ``Service`` object has a different address):
|
|
|
|
|
2020-09-02 04:58:13 +03:00
|
|
|
.. code-block:: bash
|
2020-09-01 23:04:48 +03:00
|
|
|
|
|
|
|
* Serving Flask app "singleton_scoped" (lazy loading)
|
|
|
|
* Environment: production
|
|
|
|
WARNING: This is a development server. Do not use it in a production deployment.
|
|
|
|
Use a production WSGI server instead.
|
|
|
|
* Debug mode: off
|
|
|
|
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
|
|
|
|
<__main__.Service object at 0x1099a9d90>
|
|
|
|
127.0.0.1 - - [25/Aug/2020 17:33:11] "GET / HTTP/1.1" 200 -
|
|
|
|
<__main__.Service object at 0x1099a9cd0>
|
|
|
|
127.0.0.1 - - [25/Aug/2020 17:33:17] "GET / HTTP/1.1" 200 -
|
|
|
|
<__main__.Service object at 0x1099a9d00>
|
|
|
|
127.0.0.1 - - [25/Aug/2020 17:33:18] "GET / HTTP/1.1" 200 -
|
|
|
|
<__main__.Service object at 0x1099a9e50>
|
|
|
|
127.0.0.1 - - [25/Aug/2020 17:33:18] "GET / HTTP/1.1" 200 -
|
|
|
|
<__main__.Service object at 0x1099a9d90>
|
|
|
|
127.0.0.1 - - [25/Aug/2020 17:33:18] "GET / HTTP/1.1" 200 -
|
2017-02-28 23:07:12 +03:00
|
|
|
|
|
|
|
.. disqus::
|