Skip to content

Container

provide.foundation.hub.container

TODO: Add module docstring.

Classes

Container

Container(
    hub: Hub | None = None, registry: Registry | None = None
)

Dependency Injection Container.

A focused API for dependency injection patterns, wrapping the Hub with a simpler interface for type-based registration and resolution.

This container follows the Composition Root pattern where all dependencies are registered at application startup and then resolved as needed.

Example

container = Container() container.register(DatabaseClient, db_instance) container.register(HTTPClient, http_instance)

Resolve with automatic dependency injection

service = container.resolve(MyService)

MyService.init(db, http) called automatically
Pattern

The Container is designed for the Composition Root pattern: 1. Create container at app startup (main.py) 2. Register all core dependencies 3. Resolve application entry points 4. Pass dependencies explicitly (no global access)

This matches the idiomatic patterns in Go and Rust, making it easier to adopt for developers from those ecosystems.

Initialize the DI container.

Parameters:

Name Type Description Default
hub Hub | None

Optional Hub instance (creates new if not provided)

None
registry Registry | None

Optional Registry instance (creates new if not provided)

None
Source code in provide/foundation/hub/container.py
def __init__(self, hub: Hub | None = None, registry: Registry | None = None) -> None:
    """Initialize the DI container.

    Args:
        hub: Optional Hub instance (creates new if not provided)
        registry: Optional Registry instance (creates new if not provided)
    """
    if hub is not None:
        self._hub = hub
    elif registry is not None:
        # Create a Hub with the provided registry
        from provide.foundation.context import CLIContext

        self._hub = Hub(context=CLIContext(), component_registry=registry)
    else:
        # Create a new isolated Hub
        from provide.foundation.context import CLIContext

        self._hub = Hub(context=CLIContext())
Functions
__enter__
__enter__() -> Container

Context manager entry.

Example

with Container() as container: ... container.register(Database, db) ... service = container.resolve(MyService)

Source code in provide/foundation/hub/container.py
def __enter__(self) -> Container:
    """Context manager entry.

    Example:
        >>> with Container() as container:
        ...     container.register(Database, db)
        ...     service = container.resolve(MyService)
    """
    return self
__exit__
__exit__(*args: object) -> None

Context manager exit.

Source code in provide/foundation/hub/container.py
def __exit__(self, *args: object) -> None:
    """Context manager exit."""
    # Cleanup is handled by the Hub
    pass
clear
clear() -> None

Clear all registered dependencies.

Warning

This clears the underlying Hub registry. Use with caution.

Source code in provide/foundation/hub/container.py
def clear(self) -> None:
    """Clear all registered dependencies.

    Warning:
        This clears the underlying Hub registry. Use with caution.
    """
    self._hub.clear()
get
get(type_hint: type[T]) -> T | None

Get a registered instance by type.

Parameters:

Name Type Description Default
type_hint type[T]

Type to retrieve

required

Returns:

Type Description
T | None

Registered instance or None if not found

Example

db = container.get(Database)

Source code in provide/foundation/hub/container.py
def get(self, type_hint: type[T]) -> T | None:
    """Get a registered instance by type.

    Args:
        type_hint: Type to retrieve

    Returns:
        Registered instance or None if not found

    Example:
        >>> db = container.get(Database)
    """
    # Access the component registry directly
    return self._hub._component_registry.get_by_type(type_hint)
has
has(type_hint: type[Any]) -> bool

Check if a type is registered.

Parameters:

Name Type Description Default
type_hint type[Any]

Type to check

required

Returns:

Type Description
bool

True if type is registered

Example

if container.has(Database): ... db = container.get(Database)

Source code in provide/foundation/hub/container.py
def has(self, type_hint: type[Any]) -> bool:
    """Check if a type is registered.

    Args:
        type_hint: Type to check

    Returns:
        True if type is registered

    Example:
        >>> if container.has(Database):
        ...     db = container.get(Database)
    """
    return self.get(type_hint) is not None
register
register(
    type_hint: type[T], instance: T, name: str | None = None
) -> Container

Register a dependency by type.

Parameters:

Name Type Description Default
type_hint type[T]

Type to register under

required
instance T

Instance to register

required
name str | None

Optional name for named registration

None

Returns:

Type Description
Container

Self for method chaining

Example

container.register(Database, db).register(Cache, cache)

Source code in provide/foundation/hub/container.py
def register(
    self,
    type_hint: type[T],
    instance: T,
    name: str | None = None,
) -> Container:
    """Register a dependency by type.

    Args:
        type_hint: Type to register under
        instance: Instance to register
        name: Optional name for named registration

    Returns:
        Self for method chaining

    Example:
        >>> container.register(Database, db).register(Cache, cache)
    """
    self._hub.register(type_hint, instance, name)
    return self
resolve
resolve(cls: type[T], **overrides: Any) -> T

Resolve a class with dependency injection.

Parameters:

Name Type Description Default
cls type[T]

Class to instantiate

required
**overrides Any

Explicitly provided dependencies

{}

Returns:

Type Description
T

New instance with dependencies injected

Example

service = container.resolve(MyService)

Or with overrides:

service = container.resolve(MyService, logger=custom_logger)

Source code in provide/foundation/hub/container.py
def resolve(
    self,
    cls: type[T],
    **overrides: Any,
) -> T:
    """Resolve a class with dependency injection.

    Args:
        cls: Class to instantiate
        **overrides: Explicitly provided dependencies

    Returns:
        New instance with dependencies injected

    Example:
        >>> service = container.resolve(MyService)
        >>> # Or with overrides:
        >>> service = container.resolve(MyService, logger=custom_logger)
    """
    return self._hub.resolve(cls, **overrides)

Functions

create_container

create_container() -> Container

Create a new DI container.

Convenience function for creating containers.

Returns:

Type Description
Container

New Container instance

Example

container = create_container() container.register(Database, db_instance)

Source code in provide/foundation/hub/container.py
def create_container() -> Container:
    """Create a new DI container.

    Convenience function for creating containers.

    Returns:
        New Container instance

    Example:
        >>> container = create_container()
        >>> container.register(Database, db_instance)
    """
    return Container()