当前位置:  开发笔记 > 编程语言 > 正文

在Laravel容器中覆盖Singleton

如何解决《在Laravel容器中覆盖Singleton》经验,为你挑选了2个好方法。

我想知道是否有一种简单的方法来覆盖Laravel框架核心中的单件服务集?

例如,我正在尝试使用以下提供程序重写app:name命令服务'':

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']);
        });
    }
}

我100%一切都在工作,因为无论我把服务提供商放在什么顺序(上面或下面的ConsoleSupportServiceProvider),它仍会加载原始的AppNameCommand而不是我自定义的一个.

我已经有了一个解决方案,但如果可能的话,了解未来单身人士服务的行为会很好吗?(这是使用Laravel 5.2,如果这有任何区别.)



1> 小智..:

实际上有一种更清洁的方法.您基本上想要扩展核心绑定,这可以通过使用以下extend方法来实现:

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

杰森·刘易斯有关于Laravel对国际奥委会非常好的文章Tutsplus.一定要检查一下 ;)



2> Marcin Nabia..:

我看了这个案子,看起来并不容易.如果您singleton在自定义提供程序中使用它,它将最终被默认提供程序(延迟提供程序)覆盖,因此它似乎不会那样.

在检查简单方法不起作用之后,在这种情况下您需要做的是分析Laravel注册此命令时发生的情况.

因此,在您的情况下,您首先搜索command.app.name- 您看到它在,Illuminate\Foundation\Providers\ArtisanServiceProvider并且registerAppNameCommand您可能希望覆盖的方法.

所以现在你要找出ArtisanServiceProvider它的位置 - 看看它Illuminate\Foundation\Providers\ConsoleSupportServiceProvider$providers属性中(你想要改变它).

所以最后你应该寻找发生的事情,ConsoleSupportServiceProvider你会看到它的存在config/app.php.

那么在这种情况下你需要做什么:

更改config/app.php- 更改Illuminate\Foundation\Providers\ConsoleSupportServiceProvider为您的自定义ConsoleSupportServiceProvider

在您的自定义一个,你应该从扩展\Illuminate\Foundation\Providers\ConsoleSupportServiceProvider,但改变$providersIlluminate\Foundation\Providers\ArtisanServiceProvider到自定义ArtisanServiceProvider

最后创建自定义ArtisanServiceProvider,它将从\Illuminate\Foundation\Providers\ArtisanServiceProviderregisterAppNameCommand使用自定义类覆盖的位置扩展singleton

使用这种方式你将实现你的目标(我已经验证了自定义类将用于运行命令php artisan app:name).

另外,您可能希望在您的自定义ArtisanServiceProvider删除'AppName' => 'command.app.name',$devCommands和使用您的自定义服务提供商为你呈现在您注册的单身,但我还没有尝试过这种方法.

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有