Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between App::singleton and bindShared?

The Laravel docs indicate that the appropriate way to bind a singleton is with the App::singleton() method, but internally Laravel will use the bindShared() method (for example, in TranslationServiceProvider).

I assume that the documented approach is preferred, but is there a functional difference? If not, is there any reason for having two approaches (beyond maybe historical accident)?

like image 366
Scott Buchanan Avatar asked May 29 '14 06:05

Scott Buchanan


3 Answers

I've been wondering the same thing. I don't know the motivations behind this, but I can speak to a few differences.

Here is the definition of the two methods from Laravel 4.2:

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

public function bindShared($abstract, Closure $closure)
{ 
    $this->bind($abstract, $this->share($closure), true);
}

Similarities:

  • Both methods call bind() under the hood.
  • Both methods pass true to the 3rd parameter of bind(), which signifies that this is a shared object.
  • In both cases, because this is a shared object, a call to isShared($abstract) will return true.
  • In both cases, because this is a shared object, a call to make($abstract) will return only the first instance.

Differences:

  • singleton() will accept a Closure or a string. bindShared() will only accept a Closure, not a string.
  • bindShared(), in addition to binding the object into the IOC container as a shared object, takes the additional step of wrapping the passed Closure in a share'd Closure, which prevents the passed Closure from being executed more than once. At first glance, this appears to be a double assurance that the object will be treated as a singleton. I can only guess why this might be desirable.
  • bindShared() is called 87 times inside the framework. singleton() is called 0 times.
like image 164
richardkmiller Avatar answered Nov 11 '22 06:11

richardkmiller


They are (were) functionally identical, except that bindShared() only accepts closures.

Thus bindShared() has been deprecated in Laravel 5.1 (PR 9009 - commit 829060f) and removed in Laravel 5.2 (PR 9037).

Case finally solved :)

like image 7
Gras Double Avatar answered Nov 11 '22 06:11

Gras Double


bind($abstract, $concrete, $shared) Adds $abstract as a key to the container, with $concrete being the concrete class to instantiate in its place. Mainly used for providing a concrete implementation for an interface.

share($closure) Given a closure (only), makes it act as if it was shared (instance/singleton style), and returns it. Technically equivalent to App::bind($key, $closure, true) but goes about it a different way. Mainly used in service providers to add a fully resolvable service to the IoC container.

bindShared($abstract, $closure) A shortcut that was introduced in 4.1 that caters to a common pattern. Essentially helps those who want to bind a shared instance in the container. See below for example.

singleton($abstract, $concrete) Simply an alias to bind with the $shared argument set to true. Mainly used for providing a concrete implementation for an interface, but one that should only have one instance (database connection, etc.)."

This is from http://alexrussell.me.uk/laravel-cheat-sheet/ I think this link should be helpfull

like image 2
Wesley Milan Avatar answered Nov 11 '22 06:11

Wesley Milan