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.

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Seems like I was asking IoC for some kind of black magic. Now I get it. Thank you, Lukas!
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'.

2 Comments

Shouldn't MyBindingFacade always return me an instance behind my.binding? Could you provide more information about your solution?
I've also updated my question with code sample from my WelcomeController where MyBindingFacade is used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.