VOOZH about

URL: https://deepwiki.com/calevans/staticforge/3.2-dependency-injection-container

⇱ Dependency Injection Container | calevans/staticforge | DeepWiki


Loading...
Last indexed: 11 February 2026 (5f6a2a)
Menu

Dependency Injection Container

The Dependency Injection Container is StaticForge's central service registry and configuration store. It provides a single location for storing configuration variables, registering services, and enabling dependency injection throughout the application. This document covers the Container class API, service registration patterns (stuff vs add), and how features and commands access dependencies.

For information about how the container is initialized during application startup, see Bootstrap & Initialization. For details on the services registered in the container (EventManager, FeatureManager, etc.), see their respective sections.


Container Overview

The Container class (from EICC\Utils\Container) serves two distinct purposes:

  1. Configuration Storage: Stores scalar values like directory paths, URLs, and settings via setVariable() and getVariable()
  2. Service Registry: Stores object instances and factories via add() and stuff(), enabling dependency injection

The container is instantiated once during bootstrap src/bootstrap.php129 and passed throughout the application. It acts as the single source of truth for both configuration and service instances.

Container Data Structure


Sources: src/bootstrap.php129-257


Variable Storage vs Service Storage

The container maintains two separate internal arrays for different types of data:

Variable Storage

Variables store configuration data as scalar values or arrays. They are accessed via:

  • setVariable(string $key, mixed $value): Store or overwrite a variable
  • getVariable(string $key): mixed: Retrieve a variable value
  • updateVariable(string $key, mixed $value): Update an existing variable (throws if key doesn't exist)

Use cases:

  • Directory paths: SOURCE_DIR, OUTPUT_DIR, TEMPLATE_DIR
  • URLs: SITE_BASE_URL, UPLOAD_URL
  • Settings: LOG_LEVEL, TEMPLATE
  • Site configuration: site_config array
  • Discovered files: discovered_files array

Example from bootstrap src/bootstrap.php130:


Service Storage

Services store object instances or factory closures. They are accessed via:

  • add(string $key, object $instance): Register a pre-instantiated service
  • stuff(string $key, Closure $factory): Register a lazy-loaded singleton factory
  • get(string $key): object: Retrieve a service instance

Use cases:

  • Core services: EventManager, FeatureManager, FileDiscovery
  • Singletons: logger, twig
  • Features and their dependencies

Sources: src/bootstrap.php129-257


Service Registration Patterns

StaticForge uses two distinct patterns for registering services based on instantiation timing and dependency requirements.

Pattern 1: add() for Pre-Instantiated Services

The add() method registers services that are instantiated immediately during bootstrap. Use this pattern when:

  • The service has simple construction requirements
  • The service is always needed
  • The service participates in circular dependencies (e.g., EventManager and FeatureManager)

Syntax:


Example from bootstrap src/bootstrap.php235-254:


Key characteristics:

  • Instantiated during bootstrap
  • Stored using fully-qualified class names as keys
  • Retrieved via $container->get(ServiceClass::class)
  • No lazy loading - objects exist in memory immediately

Pattern 2: stuff() for Lazy-Loaded Singletons

The stuff() method registers services as factory closures that instantiate the service only when first accessed. Use this pattern when:

  • The service is expensive to create
  • The service may not be used in every execution path
  • The service has complex initialization logic

Syntax:


Example: Logger Registration src/bootstrap.php191-205:


Example: Twig Registration src/bootstrap.php208-232:


Key characteristics:

  • Factory closure stored during bootstrap
  • Service instantiated on first get() call
  • Subsequent get() calls return same instance (singleton)
  • Can access container variables and environment via closure scope
  • Stored using string keys (not class names)

Comparison Table

Aspectadd()stuff()
RegistrationPre-instantiated objectFactory closure
InstantiationDuring registrationOn first access
Memory impactImmediateDeferred
Key formatServiceClass::classString key (e.g., 'logger')
Use caseCore services, circular depsExpensive services, optional services
SingletonYes (same instance)Yes (cached after first access)

Sources: src/bootstrap.php191-254


Service Registration Flow


Sources: src/bootstrap.php191-254


Accessing Dependencies

Different components access the container in different ways based on their lifecycle and architecture.

Features

Features receive the container during event listener invocation. The container is passed as the first parameter to all event handler methods:


Features can also store the container reference during registration src/bootstrap.php241-242:


Commands

Commands receive the container via constructor injection when registered with the Symfony Console application bin/staticforge.php:


Services

Core services receive required dependencies explicitly via constructor injection src/bootstrap.php247-248:


Services should not store the entire container unless they need dynamic access to multiple services. Instead, inject specific dependencies:


Sources: src/bootstrap.php235-254 bin/staticforge.php


Dependency Access Patterns


Sources: src/bootstrap.php235-254


Container Lifecycle

The container follows a strict lifecycle from creation to destruction:

1. Creation Phase

The container is instantiated at the beginning of bootstrap src/bootstrap.php129:


2. Variable Population Phase

Environment variables and computed values are loaded src/bootstrap.php130-186:


3. Service Registration Phase

Core services are registered using both patterns src/bootstrap.php191-254:


4. Runtime Phase

During execution, components access the container to retrieve dependencies and configuration:

  • Features receive it via event handlers
  • Commands receive it via constructor
  • Services use injected dependencies

5. Return Phase

Bootstrap returns the fully-configured container to the calling script src/bootstrap.php257:


The calling script (typically bin/staticforge.php) then uses this container to initialize the application.

Sources: src/bootstrap.php129-257


Container Usage in Tests

StaticForge's test suite provides helper methods for working with the container in unit tests tests/Unit/Features/HtmlRenderer/FeatureTest.php42-51:

Test Container Setup


Test Helper Methods

Test cases can use helper methods to manipulate the container:


Example from HtmlRenderer tests tests/Unit/Features/HtmlRenderer/FeatureTest.php42-51:


Sources: tests/Unit/Features/HtmlRenderer/FeatureTest.php25-67


Best Practices

Variable Naming Conventions

TypeConventionExample
Environment variablesSCREAMING_SNAKE_CASESITE_BASE_URL, SOURCE_DIR
System variablessnake_caseapp_root, site_config, discovered_files
Service keys (lazy)lowercaselogger, twig
Service keys (immediate)FullyQualifiedClassName::classEventManager::class

Service Registration Guidelines

Use add() when:

  • Service is always needed (EventManager, FileProcessor)
  • Service participates in circular dependencies
  • Service has simple construction
  • Service is needed immediately after bootstrap

Use stuff() when:

  • Service is expensive to instantiate (Twig Environment)
  • Service may not be needed in all execution paths
  • Service requires directory creation or validation
  • Service depends on environment configuration

Dependency Injection Guidelines

Do:

  • Inject specific dependencies via constructor
  • Pass container to event handlers
  • Use type hints for dependencies
  • Access variables via getVariable()

Avoid:

  • Storing container in services unless necessary
  • Accessing $_ENV directly (use container variables)
  • Creating new container instances
  • Modifying container structure at runtime

Sources: src/bootstrap.php191-257 tests/Unit/Features/HtmlRenderer/FeatureTest.php42-51