Skip to content

SSF Tools - Dependency Injection Architecture

Overview

The Dependency Injection (DI) architecture in SSF Tools leverages the dependency-injector library to enable modular, testable, and maintainable service composition. This architecture ensures clean separation of concerns, promotes reusability, and simplifies testing by decoupling service implementations from their consumers.

Architectural Principles

Design Goals

  • Modularity: Ensure services are loosely coupled and independently deployable.
  • Testability: Enable easy mocking and stubbing of services for unit and integration testing.
  • Configuration Management: Centralize configuration with environment-specific overrides.
  • Service Composition: Support flexible service aggregation and dependency injection.
  • Maintainability: Simplify updates and extensions to the service architecture.

Key Benefits

  • Flexibility: Easily swap implementations without modifying consumers.
  • Scalability: Support for environment-specific configurations (e.g., dev, test, prod).
  • Reusability: Shared core services reduce duplication across commands.
  • Consistency: Unified service resolution and lifecycle management.
  • Performance: Optimized lazy loading and service resolution.

Architecture Overview

graph TD CORE[Core Container<br/>Foundational Services] ENTROPY[Entropy Container<br/>Entropy Analysis Services] VOLATILITY[Volatility Container<br/>Volatility Analysis Services] APP[Application Container<br/>Main Service Aggregator] CORE --> ENTROPY CORE --> VOLATILITY ENTROPY --> APP VOLATILITY --> APP CLI[CLI Commands<br/>User Interaction] CLI --> APP CONFIG[Configuration<br/>Environment-Specific Settings] CONFIG --> CORE CONFIG --> ENTROPY CONFIG --> VOLATILITY classDef coreService fill:#e1f5fe,stroke:#0277bd,stroke-width:2px classDef component fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px classDef cli fill:#e3f2fd,stroke:#1565c0,stroke-width:2px classDef config fill:#fce4ec,stroke:#c2185b,stroke-width:2px class CORE,ENTROPY,VOLATILITY,APP coreService class CLI cli class CONFIG config

Dependency Injection Protocols

CoreContainer Protocol

The CoreContainer defines foundational services shared across the application:

from dependency_injector import containers, providers
from kp_ssf_tools.core.services.rich_output import RichOutputService
from kp_ssf_tools.core.services.http_client import HttpClientService
from kp_ssf_tools.core.services.timestamp import TimestampService

class CoreContainer(containers.DeclarativeContainer):
    """Container for core infrastructure services."""

    config = providers.Configuration()

    rich_output = providers.Singleton(
        RichOutputService,
        quiet=config.cli.quiet.as_(bool),
        verbose=config.cli.verbose.as_(bool)
    )

    http_client = providers.Singleton(
        HttpClientService,
        timeout=config.http.timeout.as_(float),
        max_retries=config.http.max_retries.as_(int),
        output_service=rich_output
    )

    timestamp = providers.Singleton(TimestampService)

ApplicationContainer Protocol

The ApplicationContainer aggregates all service containers:

from dependency_injector import containers, providers
from kp_ssf_tools.containers.core import CoreContainer
from kp_ssf_tools.containers.entropy import EntropyContainer
from kp_ssf_tools.containers.volatility import VolatilityContainer

class ApplicationContainer(containers.DeclarativeContainer):
    """Main application container that wires all services together."""

    config = providers.Configuration()

    core = providers.Container(
        CoreContainer,
        config=config
    )

    entropy = providers.Container(
        EntropyContainer,
        core=core,
        config=config
    )

    volatility = providers.Container(
        VolatilityContainer,
        core=core,
        config=config
    )

Configuration Models

Application Configuration

The configuration system supports environment-specific overrides:

from pydantic import BaseSettings, Field

class CLISettings(BaseSettings):
    quiet: bool = Field(default=False, description="Suppress output messages")
    verbose: bool = Field(default=False, description="Enable verbose output")

class HttpSettings(BaseSettings):
    timeout: float = Field(default=10.0, description="Request timeout in seconds")
    max_retries: int = Field(default=3, description="Maximum number of retries")

class ApplicationSettings(BaseSettings):
    cli: CLISettings = Field(default_factory=CLISettings)
    http: HttpSettings = Field(default_factory=HttpSettings)

    class Config:
        env_prefix = "SSF_"
        env_nested_delimiter = "__"

Default Configuration

cli:
  quiet: false
  verbose: false

http:
  timeout: 10.0
  max_retries: 3

Service Implementation

Example: EntropyAnalyzer

from kp_ssf_tools.core.services.rich_output import RichOutputProtocol
from kp_ssf_tools.core.services.timestamp import TimestampProtocol

class EntropyAnalyzer:
    def __init__(self, output_service: RichOutputProtocol, timestamp_service: TimestampProtocol):
        self.output = output_service
        self.timestamp = timestamp_service

    def analyze_file(self, file_path: str) -> dict:
        start_time = self.timestamp.utc_now()
        self.output.info(f"Analyzing {file_path}")
        # Analysis logic here
        return {"status": "success"}

CLI Integration

Example Command

from dependency_injector.wiring import inject, Provide
from kp_ssf_tools.containers import ApplicationContainer

@inject
def entropy_command(
    file_path: str,
    entropy_services=Provide[ApplicationContainer.entropy.entropy_services]
):
    analyzer = entropy_services.analyzer()
    results = analyzer.analyze_file(file_path)
    return results

Testing Patterns

Mocking Services

from unittest.mock import Mock
from kp_ssf_tools.containers import ApplicationContainer

container = ApplicationContainer()
container.core.override_providers(
    rich_output=Mock(),
    http_client=Mock()
)

Integration Testing

from kp_ssf_tools.containers import ApplicationContainer

def test_entropy_command():
    container = ApplicationContainer()
    container.config.from_dict({"cli": {"quiet": True}})
    entropy_services = container.entropy.entropy_services()
    assert entropy_services.analyzer is not None

Implementation Roadmap

Phase 1: Core Services

  • [ ] Implement CoreContainer with foundational services.
  • [ ] Define configuration models and defaults.

Phase 2: Command-Specific Containers

  • [ ] Create EntropyContainer and VolatilityContainer.
  • [ ] Wire command-specific services.

Phase 3: Application Integration

  • [ ] Aggregate containers in ApplicationContainer.
  • [ ] Implement CLI commands with DI.

Phase 4: Testing and Optimization

  • [ ] Write unit and integration tests.
  • [ ] Optimize service resolution and lazy loading.

This architecture ensures a scalable, maintainable, and testable foundation for SSF Tools.