Laravel 5 解决 ServiceProvider 中的依赖关系
Laravel 5 Resolving dependencies in ServiceProvider
我有一个 class 就像一个存储(add/get 项目)。我尝试在一个服务提供商中将其绑定为单例,并在另一个服务提供商的引导方法中解决它。
为简单起见更改了代码。
app/Providers/BindingProvider.php
<?php namespace App\Providers;
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\ServiceProvider as ServiceProvider;
class MyBindingFacade extends Facade {
public static function getFacadeAccessor() {
return 'my.binding';
}
}
class MyBinding {
protected $items = [];
public function add($name, $item) {
$this->items[$name] = $item;
}
public function get($name) {
return $this->items[$name];
}
public function getAll() {
return $this->items;
}
}
class BindingProvider extends ServiceProvider {
public function register() {
$this->app->singleton('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
}
public function provides() {
return [
'my.binding',
];
}
}
app/Providers/ResolvingProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider as ServiceProvider;
use App\Providers\MyBinding;
class ResolvingProvider extends ServiceProvider {
public function boot(MyBinding $binding) {
$binding->add('foo', 'bar');
// $manual = $this->app->make('my.binding');
// $manual->add('foo', 'bar');
}
public function register() {}
}
app/Http/Controllers/WelcomeController.php
<?php
namespace App\Http\Controllers;
use App\Providers\MyBindingFacade;
class WelcomeController extends Controller {
public function index()
{
dd(MyBindingFacade::getAll()); // debug items
}
}
当我尝试调试 WelcomeController
中的 MyBinding 状态时,我得到的是空项目数组。但是,如果我从我的 ResolvingProvider 中取消注释 $manual
部分,它 returns 一个包含 'foo' => 'bar' 的数组。这是否意味着 IoC 解析在 ServiceProvider::boot()
方法中被破坏或者我滥用了 Laravel 功能?
Laravel版本:5.0.28
更新: 添加了来自 WelcomeController 的代码示例。
在第一个例子中你没有使用 Facade,你应该使用:
use App\Providers\MyBindingFacade as MyBinding;
实际上会使用 'my.binding' 来调用它。
有了这个:
$this->app->singleton('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
你是说:my.binding
是一个单例 并解析为 App\Providers\MyBinding
.
的一个实例
这并不意味着 App\Providers\MyBinding
也注册为单例。你应该做的是:
$this->app->singleton('App\Providers\MyBinding');
$this->app->bind('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
因为 Facade 绑定使用 $app->make()
你应该得到你在上面 $this->app->singleton()
注册的相同实例。
我有一个 class 就像一个存储(add/get 项目)。我尝试在一个服务提供商中将其绑定为单例,并在另一个服务提供商的引导方法中解决它。
为简单起见更改了代码。
app/Providers/BindingProvider.php
<?php namespace App\Providers;
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\ServiceProvider as ServiceProvider;
class MyBindingFacade extends Facade {
public static function getFacadeAccessor() {
return 'my.binding';
}
}
class MyBinding {
protected $items = [];
public function add($name, $item) {
$this->items[$name] = $item;
}
public function get($name) {
return $this->items[$name];
}
public function getAll() {
return $this->items;
}
}
class BindingProvider extends ServiceProvider {
public function register() {
$this->app->singleton('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
}
public function provides() {
return [
'my.binding',
];
}
}
app/Providers/ResolvingProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider as ServiceProvider;
use App\Providers\MyBinding;
class ResolvingProvider extends ServiceProvider {
public function boot(MyBinding $binding) {
$binding->add('foo', 'bar');
// $manual = $this->app->make('my.binding');
// $manual->add('foo', 'bar');
}
public function register() {}
}
app/Http/Controllers/WelcomeController.php
<?php
namespace App\Http\Controllers;
use App\Providers\MyBindingFacade;
class WelcomeController extends Controller {
public function index()
{
dd(MyBindingFacade::getAll()); // debug items
}
}
当我尝试调试 WelcomeController
中的 MyBinding 状态时,我得到的是空项目数组。但是,如果我从我的 ResolvingProvider 中取消注释 $manual
部分,它 returns 一个包含 'foo' => 'bar' 的数组。这是否意味着 IoC 解析在 ServiceProvider::boot()
方法中被破坏或者我滥用了 Laravel 功能?
Laravel版本:5.0.28
更新: 添加了来自 WelcomeController 的代码示例。
在第一个例子中你没有使用 Facade,你应该使用:
use App\Providers\MyBindingFacade as MyBinding;
实际上会使用 'my.binding' 来调用它。
有了这个:
$this->app->singleton('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
你是说:my.binding
是一个单例 并解析为 App\Providers\MyBinding
.
这并不意味着 App\Providers\MyBinding
也注册为单例。你应该做的是:
$this->app->singleton('App\Providers\MyBinding');
$this->app->bind('my.binding', function($app) {
return $app->make('App\Providers\MyBinding');
});
因为 Facade 绑定使用 $app->make()
你应该得到你在上面 $this->app->singleton()
注册的相同实例。