Update writing of custom providers docs

This commit is contained in:
Roman Mogilatov 2015-11-23 18:45:04 +02:00
parent 9b4e325a2d
commit 1fd54927c5
3 changed files with 25 additions and 15 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,27 +1,28 @@
Writing of custom providers Writing of custom providers
------------------------ ------------------------
.. module:: dependency_injector.providers
List of *Dependency Injector* providers could be widened with custom providers. List of *Dependency Injector* providers could be widened with custom providers.
Below are some tips and recommendations that have to be met: Below are some tips and recommendations that have to be met:
1. Every custom provider has to extend base provider class - 1. Every custom provider has to extend base provider class -
``di.Provider``. :py:class:`Provider`.
2. Cusom provider's ``__init__()`` could be overriden with only condition: 2. Cusom provider's ``__init__()`` could be overriden, but parent's
parent initializer (``di.Provider.__init__()``) has to be called. initializer (:py:meth:`Provider.__init__`) has to be called.
3. Providing strategy has to be implemented in custom provider's 3. Providing strategy has to be implemented in custom provider's
``_provide()`` method. All ``*args`` & ``**kwargs`` that will be :py:meth:`Provider._provide` method. All ``*args`` & ``**kwargs``
recieved by ``di.Provider.__call__()`` will be transefed to custom that will be recieved by :py:meth:`Provider.__call__` will be
provider's ``_provide()``. transefed to custom provider's :py:meth:`Provider._provide`.
4. If custom provider is based on some standard providers, it is better to 4. If custom provider is based on some standard providers, it is better to
use delegation of standard providers, then extending of them. use delegation of standard providers, then extending of them.
5. If custom provider defines any attributes, it is good to list them in 5. If custom provider defines any attributes, it is good to list them in
``__slots__`` attribute (as *Dependency Injector* does). It can save ``__slots__`` attribute (as *Dependency Injector* does). It can save
some memory. some memory.
6. If custom provider deals with injections (e.g. ``di.Factory``, 6. If custom provider deals with injections, it is strongly recommended
``di.Singleton`` providers), it is strongly recommended to be to be consistent with :py:class:`Factory`, :py:class:`Singleton` and
consistent with ``di.Factory``, ``di.Singleton`` and ``di.Callable`` :py:class:`Callable` providers style.
providers style.
Example: Example:

View File

@ -1,24 +1,33 @@
"""Custom `di.Factory` example.""" """Custom `Factory` example."""
import dependency_injector as di from dependency_injector import providers
class User(object): class User(object):
"""Example class User.""" """Example class User."""
class UsersFactory(di.Provider): class UsersFactory(providers.Provider):
"""Example users factory.""" """Example users factory."""
__slots__ = ('_factory',) __slots__ = ('_factory',)
def __init__(self): def __init__(self):
"""Initializer.""" """Initializer."""
self._factory = di.Factory(User) self._factory = providers.Factory(User)
super(UsersFactory, self).__init__() super(UsersFactory, self).__init__()
def _provide(self, *args, **kwargs): 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
"""
return self._factory(*args, **kwargs) return self._factory(*args, **kwargs)