mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-07-08 14:23:15 +03:00
Edit abstract factory section
This commit is contained in:
parent
091dc128fd
commit
452c77cadd
|
@ -104,44 +104,24 @@ class attribute.
|
||||||
:lines: 3-
|
:lines: 3-
|
||||||
:emphasize-lines: 12-14
|
: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
|
+ Provides only objects of a specified type.
|
||||||
must be explicitly overridden before calling.
|
+ Must be overridden before usage.
|
||||||
|
|
||||||
.. note::
|
.. image:: images/abstract_factory.png
|
||||||
|
|
||||||
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
|
|
||||||
:width: 100%
|
:width: 100%
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Listing of ``cache.py``:
|
.. literalinclude:: ../../examples/providers/abstract_factory.py
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/providers/abstract_factory/cache.py
|
|
||||||
:language: python
|
|
||||||
|
|
||||||
Listing of ``example.py``:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../examples/providers/abstract_factory/example.py
|
|
||||||
:language: python
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
:emphasize-lines: 32
|
||||||
|
|
||||||
Factory aggregate providers
|
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