Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Laravel Singletons in a class?

I have registered a singleton in a service provider like so:

$this->app->singleton(MyClass::class);

This can normally be accessed by simply stating it in the parameters like so:

class FooController extends Controller
{
    public function index(MyClass $myClass)
    {
        //...
    }
}

However I cannot seem to be able to access this singleton in other custom classes (i.e. non controller classes). (https://laravel.com/docs/5.2/container#resolving)

For example like here:

class Bar {
   private $myClass;
   private $a;
   private $b;

   public function __construct($a, $b) {
      $this->a = $a;
      $this->b = $b;
      $this->myClass = ... // TODO: get singleton
   }
}

How do I do this?

Note that I will be creating multiple instances of Bar.

like image 656
Yahya Uddin Avatar asked Feb 28 '16 16:02

Yahya Uddin


3 Answers

Type-hint the class/interface in your constructor and in most cases Laravel will automatically resolve and inject it into you class.

See the Service Provider documentation for some examples and alternatives.

To go with your example:

class Bar {
    private $myClass;

    public function __construct(MyClass $myClass) {
       $this->myClass = $myClass;
    }
}

In cases where Bar::__construct takes other parameters that can not be per-defined in a service provider you will have to use a service locator:

/* $this->app is an instance of Illuminate\Foundation\Application */
$bar = new Bar($this->app->make(MyClass::class), /* other parameters */);

Alternatively, move the service location into the constructor it self:

use  Illuminate\Support\Facades\App;

class Bar {
    private $myClass;

    public function __construct() {
       $this->myClass = App::make(MyClass::class);
    }
}
like image 191
nCrazed Avatar answered Sep 19 '22 12:09

nCrazed


In later Laravel versions 6 and higher there are even more helpers to solve this:

resolve(MyClass::class);
app(MyClass::class);

& all the methods provided by the other answers

class Bar {
   private $myClass;
   private $a;
   private $b;

   public function __construct($a, $b) {
      $this->a = $a;
      $this->b = $b;
      $this->myClass = app(MyClass::class);
   }
}
like image 45
Christophvh Avatar answered Sep 20 '22 12:09

Christophvh


You can use singleton running make method of Application this way:

use Illuminate\Contracts\Foundation\Application;

class Bar {
   private $myClass;
   private $a;
   private $b;

   public function __construct($a, $b, Application $app) {
      $this->a = $a;
      $this->b = $b;
      $this->myClass = $app->make(MyClass::class);
   }
}

You can read more about this in Container resolving documentation.

like image 38
Marcin Nabiałek Avatar answered Sep 22 '22 12:09

Marcin Nabiałek