Skip to content

Dependency Injection

dependency_injection

Dependency Injection Container - Component Management.

Provides simple DI container for managing application dependencies and promoting loose coupling between components.

Classes:

Name Description
DIContainer

Dependency injection container with singleton and factory support

Classes

DIContainer

DIContainer()

Dependency injection container.

Manages singleton and factory registrations for application dependencies. Supports lazy initialization and dependency resolution.

Attributes:

Name Type Description
_singletons Dict[str, Any]

Registered singleton instances

_factories Dict[str, Callable[[], Any]]

Registered factory functions

_types Dict[str, Type]

Registered types for lazy instantiation

Methods:

Name Description
register_singleton

Register a singleton instance

register_factory

Register a factory function

register_type

Register a type for lazy instantiation

resolve

Resolve dependency by name

is_registered

Check if dependency is registered

get_registered_names

Get list of registered dependency names

clear

Clear all registrations

unregister

Unregister a dependency

Initialize DI container.

Source code in src/infrastructure/config/dependency_injection.py
def __init__(self):
    """Initialize DI container."""
    self._singletons: Dict[str, Any] = {}
    self._factories: Dict[str, Callable[[], Any]] = {}
    self._types: Dict[str, Type] = {}

    logger.info("Initialized DIContainer")
Functions
register_singleton
register_singleton(name: str, instance: Any) -> None

Register a singleton instance.

Parameters:

Name Type Description Default
name str

Dependency name

required
instance Any

Instance to register

required
Source code in src/infrastructure/config/dependency_injection.py
def register_singleton(self, name: str, instance: Any) -> None:
    """
    Register a singleton instance.

    Parameters
    ----------
    name : str
        Dependency name
    instance : Any
        Instance to register
    """
    self._singletons[name] = instance

    logger.debug(
        f"Registered singleton: {name}", extra={"type": type(instance).__name__}
    )
register_factory
register_factory(name: str, factory: Callable[[], Any]) -> None

Register a factory function.

Factory is called each time dependency is resolved.

Parameters:

Name Type Description Default
name str

Dependency name

required
factory Callable[[], Any]

Factory function that creates instances

required
Source code in src/infrastructure/config/dependency_injection.py
def register_factory(self, name: str, factory: Callable[[], Any]) -> None:
    """
    Register a factory function.

    Factory is called each time dependency is resolved.

    Parameters
    ----------
    name : str
        Dependency name
    factory : Callable[[], Any]
        Factory function that creates instances
    """
    self._factories[name] = factory

    logger.debug(f"Registered factory: {name}")
register_type
register_type(name: str, cls: Type) -> None

Register a type for lazy instantiation.

Type is instantiated (with no-arg constructor) when first resolved.

Parameters:

Name Type Description Default
name str

Dependency name

required
cls Type

Class to instantiate

required
Source code in src/infrastructure/config/dependency_injection.py
def register_type(self, name: str, cls: Type) -> None:
    """
    Register a type for lazy instantiation.

    Type is instantiated (with no-arg constructor) when first resolved.

    Parameters
    ----------
    name : str
        Dependency name
    cls : Type
        Class to instantiate
    """
    self._types[name] = cls

    logger.debug(f"Registered type: {name}", extra={"class": cls.__name__})
resolve
resolve(name: str) -> Any

Resolve dependency by name.

Resolution order: singleton, factory, type.

Parameters:

Name Type Description Default
name str

Dependency name

required

Returns:

Type Description
Any

Resolved dependency instance

Raises:

Type Description
ValueError

If dependency not found

Source code in src/infrastructure/config/dependency_injection.py
def resolve(self, name: str) -> Any:
    """
    Resolve dependency by name.

    Resolution order: singleton, factory, type.

    Parameters
    ----------
    name : str
        Dependency name

    Returns
    -------
    Any
        Resolved dependency instance

    Raises
    ------
    ValueError
        If dependency not found
    """
    # Try singleton first
    if name in self._singletons:
        return self._singletons[name]

    # Try factory
    if name in self._factories:
        instance = self._factories[name]()
        logger.debug(f"Created instance from factory: {name}")
        return instance

    # Try type (lazy singleton)
    if name in self._types:
        cls = self._types[name]
        instance = cls()
        # Cache as singleton
        self._singletons[name] = instance
        logger.debug(
            f"Created instance from type: {name}", extra={"class": cls.__name__}
        )
        return instance

    # Not found
    available = self.get_registered_names()
    raise ValueError(f"Dependency not found: '{name}'. " f"Available: {available}")
is_registered
is_registered(name: str) -> bool

Check if dependency is registered.

Parameters:

Name Type Description Default
name str

Dependency name.

required

Returns:

Type Description
bool

True if registered.

Source code in src/infrastructure/config/dependency_injection.py
def is_registered(self, name: str) -> bool:
    """
    Check if dependency is registered.

    Parameters
    ----------
    name : str
        Dependency name.

    Returns
    -------
    bool
        True if registered.
    """
    return (
        name in self._singletons or name in self._factories or name in self._types
    )
get_registered_names
get_registered_names() -> list[str]

Get list of registered dependency names.

Returns:

Type Description
list[str]

List of dependency names.

Source code in src/infrastructure/config/dependency_injection.py
def get_registered_names(self) -> list[str]:
    """
    Get list of registered dependency names.

    Returns
    -------
    list[str]
        List of dependency names.
    """
    return list(
        set(self._singletons.keys())
        | set(self._factories.keys())
        | set(self._types.keys())
    )
clear
clear() -> None

Clear all registrations.

Source code in src/infrastructure/config/dependency_injection.py
def clear(self) -> None:
    """Clear all registrations."""
    count = len(self.get_registered_names())

    self._singletons.clear()
    self._factories.clear()
    self._types.clear()

    logger.info(f"Cleared DIContainer: {count} registrations removed")
unregister
unregister(name: str) -> bool

Unregister a dependency.

Parameters:

Name Type Description Default
name str

Dependency name.

required

Returns:

Type Description
bool

True if unregistered, False if not found.

Source code in src/infrastructure/config/dependency_injection.py
def unregister(self, name: str) -> bool:
    """
    Unregister a dependency.

    Parameters
    ----------
    name : str
        Dependency name.

    Returns
    -------
    bool
        True if unregistered, False if not found.
    """
    removed = False

    if name in self._singletons:
        del self._singletons[name]
        removed = True

    if name in self._factories:
        del self._factories[name]
        removed = True

    if name in self._types:
        del self._types[name]
        removed = True

    if removed:
        logger.debug(f"Unregistered dependency: {name}")

    return removed

Functions