Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overridden core class does not work when in artisan

In a fresh Laravel build, I cannot get overridden IoC bindings to work everywhere in the application.

Suppose a service provider that overrides a core class, e.g. cache:

class NewServiceProvider extends ServiceProvider
{
    protected $defer = true;

    public function register()
    {
        $this->app->singleton('cache', function($app) {
            return new \stdClass; // demo purpose
        });
    }

    public function provides()
       {
        return ['cache'];
    }
}

The provider is then added at the bottom of app.providers config.

Now modify routes.php to the following and go check the result:

Route::get('/', function () {
    dd(app('cache'));
});

// Results in an empty stdClass being shown. It works!

However, fire up artisan tinker and do the same:

$ php artisan tinker
>>> app('cache')
=> Illuminate\Cache\CacheManager

Suddenly the override isn't working anymore...

The same behavior is encountered when processing event listeners...

Is this normal behavior and am I overlooking something? Or is this some kind of bug?

like image 823
Propaganistas Avatar asked Oct 01 '15 05:10

Propaganistas


1 Answers

I managed to track down the issue myself.

It seems Artisan loads all deferred providers at once using a key-sorted providers array:

...
"cache" => NewServiceProvider,
"cache.store" => CacheServiceProvider,
...

As you can see, the cache.store binding calls the built-in CacheServiceProvider afterwards and hence renders our cache binding useless since it contains the binding that we need to override).

So I'm obliged to have NewServiceProvider extend CacheServiceProvider, and call parent::register() to have the providers array converted to:

...
"cache" => NewServiceProvider,
"cache.store" => NewServiceProvider,
...

This seems like the only way to have the overridden cache binding being resolved correctly in Artisan.

like image 65
Propaganistas Avatar answered Oct 20 '22 10:10

Propaganistas