1

I have a class which acts like a storage (add/get item). I try to bind it as a singleton in one service provider, and resolve it in another's boot method.

The code is changed for simplicity.

app/Providers/BindingProvider.php

<?php namespace App\Providers;

use Illuminate\Support\Facades\Facade;
use Illuminate\Support\ServiceProvider as ServiceProvider;

class MyBindingFacade extends Facade {
    public static function getFacadeAccessor() {
        return 'my.binding';
    }
}

class MyBinding {

    protected $items = [];

    public function add($name, $item) {
        $this->items[$name] = $item;
    }
    public function get($name) {
        return $this->items[$name];
    }
    public function getAll() {
        return $this->items;
    }

}

class BindingProvider extends ServiceProvider {

    public function register() {
        $this->app->singleton('my.binding', function($app) {
            return $app->make('App\Providers\MyBinding');
        });
    }

    public function provides() {
        return [
            'my.binding',
        ];
    }
}

app/Providers/ResolvingProvider.php

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider as ServiceProvider;
use App\Providers\MyBinding;

class ResolvingProvider extends ServiceProvider {

    public function boot(MyBinding $binding) {
        $binding->add('foo', 'bar');

        // $manual = $this->app->make('my.binding');
        // $manual->add('foo', 'bar');
    }

    public function register() {}

}

app/Http/Controllers/WelcomeController.php

<?php
namespace App\Http\Controllers;

use App\Providers\MyBindingFacade;

class WelcomeController extends Controller {

    public function index()
    {
        dd(MyBindingFacade::getAll()); // debug items
    }
}

When I try to debug MyBinding state in my WelcomeController I'm getting empty item array. However, if I uncomment $manual part from my ResolvingProvider it returns an array containing 'foo' => 'bar'. Does it mean IoC resolution is broken in ServiceProvider::boot() method or am I misusing Laravel functionality?

Laravel version: 5.0.28

UPDATE: Added code sample from WelcomeController.

fakemeta
  • 938
  • 1
  • 8
  • 21

2 Answers2

2

With this:

$this->app->singleton('my.binding', function($app) {
    return $app->make('App\Providers\MyBinding');
});

You're saying: my.binding is a singleton and resolves to an instance of App\Providers\MyBinding.

That doesn't mean that App\Providers\MyBinding is registered as singleton too. What you should do instead is this:

$this->app->singleton('App\Providers\MyBinding');

$this->app->bind('my.binding', function($app) {
    return $app->make('App\Providers\MyBinding');
});

Because the Facade binding uses $app->make() you should get the same instance you registered with $this->app->singleton() right above.

lukasgeiter
  • 147,337
  • 26
  • 332
  • 270
0

In the first example you are not using the Facade, you should be using:

use App\Providers\MyBindingFacade as MyBinding;

Which will in fact call make it using 'my.binding'.

Antonio Carlos Ribeiro
  • 86,191
  • 22
  • 213
  • 204
  • Shouldn't `MyBindingFacade` always return me an instance behind `my.binding`? Could you provide more information about your solution? – fakemeta Apr 29 '15 at 14:58
  • I've also updated my question with code sample from my `WelcomeController` where `MyBindingFacade` is used. – fakemeta Apr 29 '15 at 15:04