覆盖核心 class 在 artisan 中不起作用
Overridden core class does not work when in artisan
在新的 Laravel 构建中,我无法覆盖 IoC 绑定以在应用程序的任何地方工作。
假设一个服务提供者覆盖了一个核心 class,例如缓存:
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'];
}
}
然后将提供程序添加到 app.providers
配置的底部。
现在将routes.php
修改为如下内容,去查看结果:
Route::get('/', function () {
dd(app('cache'));
});
// Results in an empty stdClass being shown. It works!
但是,启动 artisan tinker
并执行相同的操作:
$ php artisan tinker
>>> app('cache')
=> Illuminate\Cache\CacheManager
覆盖突然失效了...
处理事件侦听器时遇到相同的行为...
这是正常行为吗?我是不是忽略了什么?或者这是某种错误?
我设法自己找到了这个问题。
Artisan 似乎使用键排序的提供程序数组一次加载所有延迟的提供程序:
...
"cache" => NewServiceProvider,
"cache.store" => CacheServiceProvider,
...
如您所见,cache.store
绑定随后调用内置 CacheServiceProvider
并因此呈现
我们的 cache
绑定无用,因为它包含我们需要覆盖的绑定。
所以我不得不 NewServiceProvider
扩展 CacheServiceProvider
,并调用 parent::register()
将提供程序数组转换为:
...
"cache" => NewServiceProvider,
"cache.store" => NewServiceProvider,
...
这似乎是在 Artisan 中正确解析覆盖的缓存绑定的唯一方法。
在新的 Laravel 构建中,我无法覆盖 IoC 绑定以在应用程序的任何地方工作。
假设一个服务提供者覆盖了一个核心 class,例如缓存:
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'];
}
}
然后将提供程序添加到 app.providers
配置的底部。
现在将routes.php
修改为如下内容,去查看结果:
Route::get('/', function () {
dd(app('cache'));
});
// Results in an empty stdClass being shown. It works!
但是,启动 artisan tinker
并执行相同的操作:
$ php artisan tinker
>>> app('cache')
=> Illuminate\Cache\CacheManager
覆盖突然失效了...
处理事件侦听器时遇到相同的行为...
这是正常行为吗?我是不是忽略了什么?或者这是某种错误?
我设法自己找到了这个问题。
Artisan 似乎使用键排序的提供程序数组一次加载所有延迟的提供程序:
...
"cache" => NewServiceProvider,
"cache.store" => CacheServiceProvider,
...
如您所见,cache.store
绑定随后调用内置 CacheServiceProvider
并因此呈现
我们的 cache
绑定无用,因为它包含我们需要覆盖的绑定。
所以我不得不 NewServiceProvider
扩展 CacheServiceProvider
,并调用 parent::register()
将提供程序数组转换为:
...
"cache" => NewServiceProvider,
"cache.store" => NewServiceProvider,
...
这似乎是在 Artisan 中正确解析覆盖的缓存绑定的唯一方法。