laravel Ioc Container (ServiceProvider服务容器)的魔力之一:automatic dependency resolution

211 阅读2分钟

本文来自pilishen.com----原文链接; 欢迎作客我们的php&Laravel学习群:109256050

该篇属于《Laravel底层核心技术实战揭秘》这一课程《laravel底层核心概念解析》这一章的扩展阅读。由于要真正学好laravel底层,有些PHP相关的知识必须得了解,考虑到学员们的基础差异,为了避免视频当中过于详细而连篇累牍,故将一些laravel底层实现相关的PHP知识点以文章形式呈现,供大家预习和随时查阅。

在laravel的routes.php或者web.php里如下测试:

class Bar {}

Route::get('/test', function(Bar $bar){
	dd($bar);
});

之前的文章里,我们知道,要往一个函数或方法里传参,尤其是传class的实例化对象,那么之前你必须得有个实例,说白了就是得new一下,但是上面的代码没瞅见有传参过程,只是这个route的回调函数里期望传入一个Class Bar的实例$bar,没有实例化过程,这能行吗?

Bar {#250}

咦?居然可以!

好,既然你可以,先不管别的,我再给你整的复杂些:

class Baz {}

class Bar {
	
	protected $baz;
	public function __construct(Baz $baz)
	{
		$this->baz = $baz;
	}
}

Route::get('/test', function(Bar $bar){
	dd($bar);
});

看你这次还行?

Bar {#253 ▼
  #baz: Baz {#255}
}

呀!厉害了——我可没有给你传new Bar(new Baz)进去啊!

也即是说,不论是在route回调函数里,还是在controller里,还是其他相关地方,laravel的IoC Container能自动进行依赖解析、注入,像上面的例子,它能知道我们期望传入一个Class Bar的实例$bar,然后自动背后给我们创建了一个,同时,它也能知道Class Bar的constructor中需要传入一个Class Baz实例,也进一步给我们创建了。所以,这整个过程中,我们不需要去手动new

可能,之前你有自己查看过laravel的源码,在层层依赖的情况下,你会发现明明其间很多class都有constructor,都需要传入dependency,但是laravel在调用的过程中,啥也没给传,按照之前的思路,这根本行不通嘛~

那么现在,咱们知道laravel的Container能自动解析依赖(automatic dependency resolution),虽然现在还不清楚它背后具体怎么实现,至少不影响继续往下看源码了。

至于具体是怎么实现的,以及咱们能否自己写一个这样的功能,然后用在自己的框架里,这些我们在《Laravel底层核心技术实战揭秘》相应章节具体呈现~