foundation/documentation/dependency-injection.md
2025-06-13 18:29:55 +02:00

3.3 KiB

Dependency Injection Container

This document provides comprehensive information about the Foundation framework's dependency injection container system, including the enhanced InflectableContainer and its advanced features.

Overview

Foundation uses a custom InflectableContainer that wraps PHP-DI and provides additional features:

  • Container Inflection: Automatic method invocation during object resolution
  • Smart Parameter Resolution: Intelligent detection of class names vs static values
  • Simplified Service Registration: Clean syntax for dependency declaration
  • Unit of Work Integration: Seamless persistence layer coordination

Container Architecture

InflectableContainer

The InflectableContainer is a wrapper around PHP-DI that provides enhanced functionality while maintaining full compatibility with PSR-11.

use Foundation\Core\DependencyInjection\InflectableContainer;

// Created via ContainerFactory
$container = ContainerFactory::create();

Service Registration

Basic Registration

Register services with explicit dependencies:

// Simple service with dependencies
$container->register(FetchAllActivitiesFromDatabase::class, [\PDO::class]);

// Multiple dependencies
$container->register(ActivityApiController::class, [
    FetchAllActivities::class,
    SetAllActivitiesAsRead::class
]);

Interface Binding

Bind interfaces to concrete implementations:

$container->bind(ActivityRepositoryInterface::class, ActivityRepository::class, [
    FetchAllActivitiesFromDatabase::class,
    SetAllActivitiesAsReadInDatabase::class,
    UnitOfWorkInterface::class
]);

Advanced Registration

// No dependencies (uses auto-wiring)
$container->register(SimpleService::class);

// Custom factory closure (when needed)
$container->set(ComplexService::class, function (InflectableContainer $container) {
    $service = new ComplexService();
    $service->configure($container->get(AppConfig::class));
    return $service;
});

Container Inflection

Container inflection allows you to automatically invoke methods on resolved objects. This is particularly useful for cross-cutting concerns and modular registration.

Basic Inflection

// Register a persister to the UnitOfWork when it's created
$container->inflect(UnitOfWork::class)
          ->invokeMethod('registerPersister', [ActivityPersister::class]);

Smart Parameter Resolution

The inflection system automatically detects what needs container resolution:

// Mixed parameters: class + static values
$container->inflect(EmailService::class)
          ->invokeMethod('configure', [LoggerInterface::class, 'smtp.example.com']);

// Resolves: LoggerInterface → instance, 'smtp.example.com' → static string

Multiple Inflections

$container->inflect(DatabaseService::class)
          ->invokeMethod('setLogger', [LoggerInterface::class])
          ->invokeMethod('setEnvironment', ['production'])
          ->invokeMethod('addMiddleware', [AuthMiddleware::class]);

Interface-Based Inflection

Inflect on interfaces for broader application:

// Apply to all classes implementing LoggerAwareInterface
$container->inflect(LoggerAwareInterface::class)
          ->invokeMethod('setLogger', [LoggerInterface::class]);