"""`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() must be # overridden before calling