mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-05-23 05:56:19 +03:00
Edit abstract factory section
This commit is contained in:
parent
091dc128fd
commit
452c77cadd
|
@ -104,44 +104,24 @@ class attribute.
|
|||
:lines: 3-
|
||||
:emphasize-lines: 12-14
|
||||
|
||||
.. _abstract_factory_providers:
|
||||
Abstract factory
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Abstract factory providers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
:py:class:`AbstractFactory` provider helps when you need to create a provider of some base class
|
||||
and the particular implementation is not yet know. ``AbstractFactory`` provider is a ``Factory``
|
||||
provider with two peculiarities:
|
||||
|
||||
:py:class:`AbstractFactory` provider is a :py:class:`Factory` provider that
|
||||
must be explicitly overridden before calling.
|
||||
+ Provides only objects of a specified type.
|
||||
+ Must be overridden before usage.
|
||||
|
||||
.. note::
|
||||
|
||||
Overriding of :py:class:`AbstractFactory` provider is possible only by
|
||||
another :py:class:`Factory` provider.
|
||||
|
||||
:py:class:`AbstractFactory` provider is useful when it is needed to specify
|
||||
explicitly that it only provides abstraction, but not an implementation.
|
||||
Client code must override such factories with factories that provide particular
|
||||
implementations. Otherwise, :py:class:`AbstractFactory` will raise an error
|
||||
on attempt of calling it. At the same time, :py:class:`AbstractFactory` is
|
||||
regular provider that could be injected into other providers (or used for
|
||||
any other kind of bindings) without being overridden. After
|
||||
:py:class:`AbstractFactory` provider has been overridden, its behaviour is
|
||||
identical to regular :py:class:`Factory` provider.
|
||||
|
||||
Example:
|
||||
|
||||
.. image:: /images/providers/abstract_factory.png
|
||||
.. image:: images/abstract_factory.png
|
||||
:width: 100%
|
||||
:align: center
|
||||
|
||||
Listing of ``cache.py``:
|
||||
|
||||
.. literalinclude:: ../../examples/providers/abstract_factory/cache.py
|
||||
:language: python
|
||||
|
||||
Listing of ``example.py``:
|
||||
|
||||
.. literalinclude:: ../../examples/providers/abstract_factory/example.py
|
||||
.. literalinclude:: ../../examples/providers/abstract_factory.py
|
||||
:language: python
|
||||
:lines: 3-
|
||||
:emphasize-lines: 32
|
||||
|
||||
Factory aggregate providers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
BIN
docs/providers/images/abstract_factory.png
Normal file
BIN
docs/providers/images/abstract_factory.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
75
examples/providers/abstract_factory.py
Normal file
75
examples/providers/abstract_factory.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
"""`AbstractFactory` providers example."""
|
||||
|
||||
import abc
|
||||
import dataclasses
|
||||
import random
|
||||
from typing import List
|
||||
|
||||
from dependency_injector import providers
|
||||
|
||||
|
||||
class AbstractCacheClient(metaclass=abc.ABCMeta):
|
||||
...
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class RedisCacheClient(AbstractCacheClient):
|
||||
host: str
|
||||
port: int
|
||||
db: int
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class MemcachedCacheClient(AbstractCacheClient):
|
||||
hosts: List[str]
|
||||
port: int
|
||||
prefix: str
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Service:
|
||||
cache: AbstractCacheClient
|
||||
|
||||
|
||||
cache_client_factory = providers.AbstractFactory(AbstractCacheClient)
|
||||
service_factory = providers.Factory(
|
||||
Service,
|
||||
cache=cache_client_factory,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cache_type = random.choice(['redis', 'memcached', None])
|
||||
|
||||
if cache_type == 'redis':
|
||||
cache_client_factory.override(
|
||||
providers.Factory(
|
||||
RedisCacheClient,
|
||||
host='localhost',
|
||||
port=6379,
|
||||
db=0,
|
||||
),
|
||||
)
|
||||
elif cache_type == 'memcached':
|
||||
cache_client_factory.override(
|
||||
providers.Factory(
|
||||
MemcachedCacheClient,
|
||||
hosts=['10.0.1.1'],
|
||||
port=11211,
|
||||
prefix='my_app',
|
||||
),
|
||||
)
|
||||
|
||||
service = service_factory()
|
||||
print(service.cache)
|
||||
# The output depends on cache_type variable value.
|
||||
#
|
||||
# If the value is 'redis':
|
||||
# RedisCacheClient(host='localhost', port=6379, db=0)
|
||||
#
|
||||
# If the value is 'memcached':
|
||||
# MemcachedCacheClient(hosts=['10.0.1.1'], port=11211, prefix='my_app')
|
||||
#
|
||||
# If the value is None:
|
||||
# Error: AbstractFactory(<class '__main__.AbstractCacheClient'>) must be
|
||||
# overridden before calling
|
|
@ -1,25 +0,0 @@
|
|||
"""Example hierarchy of cache clients with abstract base class."""
|
||||
|
||||
|
||||
class AbstractCacheClient:
|
||||
"""Abstract cache client."""
|
||||
|
||||
|
||||
class RedisCacheClient(AbstractCacheClient):
|
||||
"""Cache client implementation based on Redis."""
|
||||
|
||||
def __init__(self, host, port, db):
|
||||
"""Initialize instance."""
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.db = db
|
||||
|
||||
|
||||
class MemcacheCacheClient(AbstractCacheClient):
|
||||
"""Cache client implementation based on Memcached."""
|
||||
|
||||
def __init__(self, hosts, port, prefix):
|
||||
"""Initialize instance."""
|
||||
self.hosts = hosts
|
||||
self.port = port
|
||||
self.prefix = prefix
|
|
@ -1,36 +0,0 @@
|
|||
"""`AbstractFactory` providers example."""
|
||||
|
||||
import cache
|
||||
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
|
||||
# Define abstract cache client factory:
|
||||
cache_client_factory = providers.AbstractFactory(cache.AbstractCacheClient)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Override abstract factory with redis client factory:
|
||||
cache_client_factory.override(
|
||||
providers.Factory(
|
||||
cache.RedisCacheClient,
|
||||
host='localhost',
|
||||
port=6379,
|
||||
db=0,
|
||||
),
|
||||
)
|
||||
redis_cache = cache_client_factory()
|
||||
print(redis_cache)
|
||||
# <cache.RedisCacheClient object at 0x10975bc50>
|
||||
|
||||
# Override abstract factory with memcache client factory:
|
||||
cache_client_factory.override(
|
||||
providers.Factory(
|
||||
cache.MemcacheCacheClient,
|
||||
hosts=['10.0.1.1', '10.0.1.2', '10.0.1.3'],
|
||||
port=11211,
|
||||
prefix='my_app',
|
||||
),
|
||||
)
|
||||
memcache_cache = cache_client_factory()
|
||||
print(memcache_cache)
|
||||
# <cache.MemcacheCacheClient object at 0x10975bc90>
|
Loading…
Reference in New Issue
Block a user