.. _singleton-provider: Singleton provider ================== .. 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. .. currentmodule:: dependency_injector.providers :py:class:`Singleton` provider provides single object. It memorizes the first created object and returns it on the rest of the calls. .. literalinclude:: ../../examples/providers/singleton.py :language: python :lines: 3- ``Singleton`` provider handles dependencies injection the same way like a :ref:`factory-provider`. .. note:: ``Singleton`` provider makes dependencies injection only when creates an object. When an object is created and memorized ``Singleton`` provider just returns it without applying injections. Specialization of the provided type and abstract singletons work the same like like for the factories: - :ref:`factory-specialize-provided-type` - :ref:`abstract-factory` ``Singleton`` provider scope is tied to the container. Two different containers will provider two different singleton objects: .. literalinclude:: ../../examples/providers/singleton_multiple_containers.py :language: python :lines: 3- Resetting memorized object -------------------------- To reset a memorized object you need to call the ``.reset()`` method of the ``Singleton`` provider. .. literalinclude:: ../../examples/providers/singleton_resetting.py :language: python :lines: 3- :emphasize-lines: 18 .. note:: Resetting of the memorized object clears the reference to it. Further object's lifecycle is managed by the garbage collector. You can use ``.reset()`` method with a context manager. Memorized instance will be reset on both entering and exiting a context. .. literalinclude:: ../../examples/providers/singleton_resetting_with.py :language: python :lines: 3- :emphasize-lines: 18-19 Context manager ``.reset()`` returns resetting singleton provider. You can use it for aliasing. .. code-block:: python with container.user_service.reset() as user_service: ... Method ``.reset()`` resets only current provider. To reset all dependent singleton providers call ``.full_reset()`` method. .. literalinclude:: ../../examples/providers/singleton_full_resetting.py :language: python :lines: 3- :emphasize-lines: 25 Method ``.full_reset()`` supports context manager interface like ``.reset()`` does. .. code-block:: python with container.user_service.full_reset() as user_service: ... See also: :ref:`reset-container-singletons`. Using singleton with multiple threads ------------------------------------- ``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. There are two thread-safe singleton implementations out of the box: + :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. .. literalinclude:: ../../examples/providers/singleton_thread_locals.py :language: python :lines: 3- :emphasize-lines: 13,15 Implementing scopes ------------------- To implement a scoped singleton provider use a ``Singleton`` provider and reset its scope when needed. .. literalinclude:: ../../examples/providers/singleton_scoped.py :language: python :lines: 3- The output should look like this (each request a ``Service`` object has a different address): .. code-block:: bash * 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 - .. disqus::