我想知道是否有一种简单的方法来覆盖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,如果这有任何区别.)
实际上有一种更清洁的方法.您基本上想要扩展核心绑定,这可以通过使用以下extend
方法来实现:
$this->app->extend('command.app.name', function ($command, $app) { return new AppNameCommand($app['composer'], $app['files']); });
杰森·刘易斯有关于Laravel对国际奥委会非常好的文章Tutsplus.一定要检查一下 ;)
我看了这个案子,看起来并不容易.如果您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
,但改变$providers
从Illuminate\Foundation\Providers\ArtisanServiceProvider
到自定义ArtisanServiceProvider
最后创建自定义ArtisanServiceProvider
,它将从\Illuminate\Foundation\Providers\ArtisanServiceProvider
您registerAppNameCommand
使用自定义类覆盖的位置扩展singleton
使用这种方式你将实现你的目标(我已经验证了自定义类将用于运行命令php artisan app:name
).
另外,您可能希望在您的自定义ArtisanServiceProvider
删除'AppName' => 'command.app.name',
从$devCommands
和使用您的自定义服务提供商为你呈现在您注册的单身,但我还没有尝试过这种方法.