在一个全新的Laravel版本中,我无法覆盖IoC绑定,无法在应用程序的任何位置工作。
假设一个覆盖核心类的服务提供者,例如:缓存:
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
config。
现在将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
突然间覆盖不再起作用了......
处理事件侦听器时会遇到相同的行为......
这是正常行为吗?我忽略了什么吗?或者这是某种错误?
答案 0 :(得分:4)
我设法自己追查这个问题。
似乎Artisan使用密钥排序的提供程序数组一次加载所有延迟提供程序:
...
"cache" => NewServiceProvider,
"cache.store" => CacheServiceProvider,
...
如您所见,cache.store
绑定后来调用内置CacheServiceProvider
因此呈现
我们的cache
绑定没用,因为它包含我们需要覆盖的绑定。
所以我有义务NewServiceProvider
延长CacheServiceProvider
,并致电parent::register()
让提供者数据转换为:
...
"cache" => NewServiceProvider,
"cache.store" => NewServiceProvider,
...
这似乎是在Artisan中正确解析被覆盖的缓存绑定的唯一方法。