Override Singleton in Laravel Container

Ad

I'm wondering if there's a simple way to override a singleton service set in the core of the Laravel framework?

e.g. I'm trying to rewrite the app:name command service '' with the following provider:

use Hexavel\Console\AppNameCommand;
use Illuminate\Console\Events\ArtisanStarting;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\ServiceProvider;

class NameCommandProvider extends ServiceProvider
{
    /**
     * Register any other events for your application.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function boot(Dispatcher $events)
    {
        $events->listen(ArtisanStarting::class, function ($event) {
            $event->artisan->resolve('command.app.name');
        }, -1);
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('command.app.name', function ($app) {
            return new AppNameCommand($app['composer'], $app['files']);
        });
    }
}

I'm 100% everything is working due to extensive checks put no matter what order I put my service provider (above or below ConsoleSupportServiceProvider) it still loads the original AppNameCommand over my custom one.

I've already got a work around BUT it would be nice to know about the behaviour of singleton services for the future if this is at all possible? (This is using Laravel 5.2 if that makes any difference.)

Ad

Answer

Ad

There's actually a cleaner way to do this. You basically want to extend a core binding, which can be achieved by using the extend method:

$this->app->extend('command.app.name', function ($command, $app) {
    return new AppNameCommand($app['composer'], $app['files']);
});

Jason Lewis has a really nice article regarding Laravel's IoC on Tutsplus. Make sure to check it out ;)

Ad
source: stackoverflow.com
Ad