python-dependency-injector/examples/providers/abstract_factory.py

80 lines
1.8 KiB
Python

"""`AbstractFactory` providers example."""
import abc
import dataclasses
import random
from typing import List
from dependency_injector import containers, 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
class Container(containers.DeclarativeContainer):
cache_client_factory = providers.AbstractFactory(AbstractCacheClient)
service_factory = providers.Factory(
Service,
cache=cache_client_factory,
)
if __name__ == '__main__':
container = Container()
cache_type = random.choice(['redis', 'memcached'])
if cache_type == 'redis':
container.cache_client_factory.override(
providers.Factory(
RedisCacheClient,
host='localhost',
port=6379,
db=0,
),
)
elif cache_type == 'memcached':
container.cache_client_factory.override(
providers.Factory(
MemcachedCacheClient,
hosts=['10.0.1.1'],
port=11211,
prefix='my_app',
),
)
service = container.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