Skip to content
Advertisement

Laravel container and shared instances

I am wondering how Laravel differentiates between singletons(shared instances) and concrete implementations that might be overwritten inside the container.

The container has a bind method that looks like this:

public function bind($abstract, $concrete = null, $shared = false)
{        
    // If no concrete type was given, we will simply set the concrete type to the
    // abstract type. After that, the concrete type to be registered as shared
    // without being forced to state their classes in both of the parameters.
    $this->dropStaleInstances($abstract);

    if (is_null($concrete)) {
        $concrete = $abstract;
    }

    // If the factory is not a Closure, it means it is just a class name which is
    // bound into this container to the abstract type and we will just wrap it
    // up inside its own Closure to give us more convenience when extending.
    if (!$concrete instanceof Closure) {
        $concrete = $this->getClosure($abstract, $concrete);
    }

    $this->bindings[$abstract] = compact('concrete', 'shared');

    // If the abstract type was already resolved in this container we'll fire the
    // rebound listener so that any objects which have already gotten resolved
    // can have their copy of the object updated via the listener callbacks.
    if ($this->resolved($abstract)) {
        $this->rebound($abstract);
    }
}

It also has a singleton method that calls this function but with the $shared argument always being true like so:

public function singleton($abstract, $concrete = null)
{
    $this->bind($abstract, $concrete, true);
}

The difference here being that although they both are bound in the $bindings property the singleton set it like so:

[concrete, true]

How does this make it a singleton though if there seems to be no check if it has already been set or not? Nowhere can I find whether it does anything with the $shared variable we set.

Besides that there is also another property in this class called:

/**
 * The container's shared instances.
 *
 * @var array
 */
protected $instances = [];

It would seem logical for a singleton to end up here, so what exactly does this

Example of the bind method:

https://github.com/laravel/framework/blob/5.3/src/Illuminate/Container/Container.php#L178

Advertisement

Answer

bind() method saves $shared here. Then make() method is using isShared() method for checking if $shared is set and then for checking if it’s true or false here.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement