其实laravel中的服务容器就是一个依赖容器,依赖容器是什么,请看下文。
依赖注入
当一个系统变复杂后,经常会遇到A类需要B类的方法,B类需要C类的方法这样的情况。传统的思路下,我们会这么写:
class Bim { public function doSomething() { echo __METHOD__,'|'; } } class Bar { public function doSomething() { $bim = new Bim(); $bim->doSomething(); echo __METHOD__,'|'; } } class Foo { public function doSomething() { $bar = new Bar(); $bar->doSomething(); echo __METHOD__; } } $foo = new Foo(); $foo->doSomething();
应用依赖注入的思想(依赖注入听上去很花哨,其实质是通过构造函数或者某些情况下通过 set 方法将类依赖注入到类中):
改成这样:
class Bim { public function doSomething() { echo __METHOD__,'|'; } } class Bar { private $bim; public function __construct(Bim $bim) { $this->bim = $bim; } public function doSomething() { $this->bim->doSomething(); echo __METHOD__,'|'; } } class Foo { private $bar; public function __construct(Bar $bar) { $this->bar = $bar; } public function doSomething() { $this->bar->doSomething(); echo __METHOD__; } } $foo = new Foo(new Bar(new Bim())); $foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
依赖容器
上面类的实例化还是我们手动new的,依赖容器的作用就是把类的实例化管理起来,应用程序需要到Foo类,就从容器内取得Foo类,容器创建Bim类,再创建Bar类并把Bim注入,再创建Foo类,并把Bar注入,应用程序调用Foo方法,Foo调用Bar方法,接着做些其它工作。
上面应用依赖容器后(这段代码来自Twittee):
class Container { private $s = array(); function __set($k,$c) { $this->s[$k] = $c; } function __get($k) { return $this->s[$k]($this); } } $c = new Container(); $c->bim = function () { return new Bim(); }; $c->bar = function ($c) { return new Bar($c->bim); }; $c->foo = function ($c) { return new Foo($c->bar); }; // 从容器中取得Foo $foo = $c->foo; $foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
laravel中服务提供者
看看官方的例子:
注册一个服务:
use Riak\Connection; use Illuminate\Support\ServiceProvider; class TestServiceProvider extends ServiceProvider { /** * 在容器中注册绑定。 * * @return void */ public function register() { //使用singleton绑定单例 $this->app->singleton('test',function(){ return new TestService(); }); } }
有没有发现register方法其实就是往依赖容器里设置一个类。然后官方文档也说了,
$this->app就是一个服务容器,听名字也知道了其实就是依赖容器。