Skip to main content

Container Bindings

Overview

The DomainFlow Container allows you to register (or bind) an identifier — such as a class name, interface, or alias—to a callable or concrete class. When you later request that identifier (via methods like $container->make(...) or $container->get(...)), the container automatically instantiates or retrieves the corresponding object.


Rebinding and Retained State

Calling bind() (or singleton()) again for an identifier that already has a retained shared instance always discards that instance first — the next resolution rebuilds it from the new binding. instance() replaces a retained value directly.

has() reports explicit bindings, instances, and aliases, and also returns true for an existing instantiable class that the container can autowire. Resolving such an unbound class does not register it; the result is still transient unless you explicitly bind it as shared.


Key Binding Methods

bind()

Registers a binding from an abstract identifier to a concrete implementation.

Method Signature:

bind(
string $abstract,
Closure|string|null $concrete,
bool $shared = false
)
ParameterTypeRequired
$abstractstringYes
$concreteClosure, string, or nullOptional (default null)
$sharedboolOptional (default false)

Notes:

  • If $concrete is null, the container uses the abstract identifier as the concrete implementation.
  • If $shared is set to true, the binding behaves like a singleton, ensuring only one instance is created.

singleton()

A shortcut for binding a service as a singleton.

Method Signature:

singleton(
string $abstract,
Closure|string|null $concrete
)
ParameterTypeRequired
$abstractstringYes
$concreteClosure, string, or nullOptional (default null)

Note:
This is equivalent to calling bind() with the $shared flag set to true.


instance()

Binds an already-created instance to an abstract identifier.

Method Signature:

instance(
string $abstract,
mixed $instance
)
ParameterTypeRequired
$abstractstringYes
$instancemixedYes

Note:
This method stores an already available value. Despite the method name, $instance may be any PHP value, not only an object; the same stored value is returned every time the identifier is resolved.


alias()

Registers an alternate identifier that resolves to an existing abstract.

Method Signature:

alias(
string $abstract,
string $alias
)
ParameterTypeRequired
$abstractstringYes
$aliasstringYes

Note:
Once registered, resolving $alias (via make(), get(), or array access) transparently resolves $abstract instead. has() also follows the alias when checking existence. Aliases are commonly used to give a friendlier or interface-agnostic name to a concrete binding, e.g. $container->alias(DatabaseConnection::class, 'db').


Comparing the Binding Methods

  • bind()
    Defines how the container should create a service. By default, each call to make produces a new instance unless $shared is true.

  • singleton()
    A convenient way to register a binding that should only ever be instantiated once. It internally calls bind() with the shared flag enabled.

  • instance()
    Directly registers an already available value, making it immediately available without any further instantiation.

  • alias()
    Doesn't register a new binding by itself — it points a second identifier at one that (usually) already exists, so both resolve to the same thing.


Example Usage

Singleton Binding Example

$container = new Container();

// Register a singleton binding for DatabaseConnection.
// The provided closure will only be executed once.
$container->singleton(DatabaseConnection::class, function () {
return new MySqlConnection();
});

// Both calls to get() return the same instance.
$db1 = $container->get(DatabaseConnection::class);
$db2 = $container->get(DatabaseConnection::class);

In this example, every time you resolve DatabaseConnection::class, the container returns the same instance of MySqlConnection.


Summary

Container bindings in DomainFlow provide a flexible way to manage your service dependencies. Whether you're registering a new service using a factory, setting up a singleton, or storing an existing instance, these methods streamline dependency management and promote cleaner, more modular application code.