iviphp/container

Dependency injection container for the IviPHP ecosystem.

Maintainers

Package info

github.com/iviphp/container

pkg:composer/iviphp/container

Transparency log

Statistics

Installs: 4

Dependents: 1

Suggesters: 0

Stars: 1

Open Issues: 0

v0.1.0 2026-07-21 10:59 UTC

This package is not auto-updated.

Last update: 2026-07-21 20:34:52 UTC


README

Dependency injection container for the IviPHP ecosystem.

Overview

iviphp/container provides a lightweight dependency injection container for IviPHP packages and applications.

It supports:

  • explicit service bindings;
  • singleton services;
  • existing instances;
  • closure factories;
  • automatic constructor injection;
  • circular dependency detection.

The container can resolve concrete classes automatically through PHP reflection.

Installation

composer require iviphp/container

Requirements

  • PHP 8.2 or later
  • Composer
  • iviphp/contracts

Creating a container

<?php

declare(strict_types=1);

use Ivi\Container\Container;

$container = new Container();

Automatic constructor injection

Concrete classes do not need to be registered manually when their dependencies can also be resolved.

<?php

declare(strict_types=1);

use Ivi\Container\Container;

final class Database
{
}

final class UserRepository
{
    public function __construct(
        private Database $database
    ) {}
}

$container = new Container();

$repository = $container->get(UserRepository::class);

The container automatically creates Database and injects it into UserRepository.

Registering bindings

An interface can be connected to a concrete implementation.

<?php

declare(strict_types=1);

use Ivi\Container\Container;

interface LoggerInterface
{
    public function log(string $message): void;
}

final class FileLogger implements LoggerInterface
{
    public function log(string $message): void
    {
        // Write the message to a file.
    }
}

$container = new Container();

$container->bind(
    LoggerInterface::class,
    FileLogger::class
);

$logger = $container->get(LoggerInterface::class);

A binding creates a new instance each time it is resolved.

$first = $container->get(LoggerInterface::class);
$second = $container->get(LoggerInterface::class);

$first !== $second;

Singleton services

Singleton services are resolved once and reused.

$container->singleton(
    LoggerInterface::class,
    FileLogger::class
);

$first = $container->get(LoggerInterface::class);
$second = $container->get(LoggerInterface::class);

$first === $second;

Closure factories

A closure can be used when service creation requires custom logic.

$container->bind(
    LoggerInterface::class,
    static function (Container $container): LoggerInterface {
        return new FileLogger();
    }
);

Factories receive the current container instance.

$container->singleton(
    UserRepository::class,
    static fn(Container $container): UserRepository =>
        new UserRepository(
            $container->get(Database::class)
        )
);

A factory must return an object.

Registering existing instances

An existing object can be stored directly in the container.

$database = new Database();

$container->instance(
    Database::class,
    $database
);

$resolved = $container->get(Database::class);

$resolved === $database;

Registered instances are always shared.

Checking services

if ($container->has(LoggerInterface::class)) {
    $logger = $container->get(LoggerInterface::class);
}

Concrete classes are considered resolvable even when they have not been explicitly registered.

Removing services

Remove a binding and its resolved singleton instance:

$container->forget(LoggerInterface::class);

Remove every binding and resolved instance:

$container->flush();

Constructor parameter resolution

The container resolves class dependencies automatically.

final class Service
{
    public function __construct(
        private UserRepository $repository
    ) {}
}

Parameters with default values are supported.

final class Service
{
    public function __construct(
        private string $environment = 'production'
    ) {}
}

Nullable unresolved parameters receive null.

final class Service
{
    public function __construct(
        private ?string $name = null
    ) {}
}

Scalar parameters without a default value cannot be resolved automatically.

final class Service
{
    public function __construct(
        private string $name
    ) {}
}

Resolving this class throws a BindingResolutionException.

Circular dependency detection

Circular dependency chains are detected during resolution.

final class FirstService
{
    public function __construct(
        SecondService $second
    ) {}
}

final class SecondService
{
    public function __construct(
        FirstService $first
    ) {}
}

Resolving either service throws a BindingResolutionException describing the dependency chain.

Available methods

$container->bind($abstract, $concrete);
$container->singleton($abstract, $concrete);
$container->instance($abstract, $instance);

$container->has($abstract);
$container->get($abstract);
$container->make($abstract);

$container->forget($abstract);
$container->flush();

Exceptions

ContainerException

Base exception for container-related failures.

BindingResolutionException

Thrown when the container cannot resolve a service because of:

  • a missing class;
  • a non-instantiable class or interface;
  • an unresolved constructor parameter;
  • a circular dependency;
  • an invalid factory return value;
  • a construction failure.

Design principles

  • Small and predictable API
  • Automatic constructor injection
  • Explicit interface bindings
  • No global container instance
  • No framework runtime dependency
  • Clear dependency resolution errors
  • No hidden service locator behavior

This package is responsible only for registering and resolving application dependencies.

Service providers, application bootstrapping and framework lifecycle management belong to higher-level IviPHP packages.

Ecosystem

This package is part of the IviPHP ecosystem:

  • iviphp/contracts
  • iviphp/support
  • iviphp/config
  • iviphp/http
  • iviphp/validation
  • iviphp/database
  • iviphp/cache
  • iviphp/view
  • iviphp/framework

Contributing

Contributions should preserve the focused scope of this package.

New features should:

  • remain independent from the full framework;
  • preserve predictable dependency resolution;
  • avoid introducing global container state;
  • provide clear errors when a dependency cannot be resolved;
  • avoid unrelated application lifecycle responsibilities.

Security

Please report security issues privately to the Softadastra maintainers instead of opening a public issue.

License

This project is licensed under the MIT License.

Maintainer

Created and maintained by Softadastra.