依赖注入
laravel依赖注入是A类在依赖B类时,可以直接在容器中直接注入B类和A类,容器会自己去寻找依赖,而不用担心A类和B类谁先注入到容器。
新建立两个文件(注意这两个文件的namespace),一个是:
<?phpnamespace App\Http\Controllers\User;class People{public $dog = null;/*** People constructor.* @param \App\Http\Controllers\User\Dog $dog*/public function __construct(Dog $dog){$this->dog = $dog;}public function putDog(){return $this->dog->dogCall();}}
另一个是:
<?phpnamespace App\Http\Controllers\User;class Dog{public function dogCall(){return '汪汪汪';}}
在route中建立一条路由:
Route::get('user/test', 'User\UserController@test');
最后建立一个contorller
<?phpnamespace App\Http\Controllers\User;use Illuminate\Foundation\Bus\DispatchesJobs;use Illuminate\Routing\Controller as BaseController;use Illuminate\Foundation\Validation\ValidatesRequests;use Illuminate\Foundation\Auth\Access\AuthorizesRequests;use Illuminate\Contracts\Container\Container;class UserController extends BaseController{use AuthorizesRequests, DispatchesJobs, ValidatesRequests;public function test(Container $container){/*People类和Dog类也可以在config/App.php中注入,就不用在这里注入了'aliases' => ['Dog' => App\Http\Controllers\User\Dog::class,'People' => App\Http\Controllers\User\People::class,]*/$container->bind('People', 'App\Http\Controllers\User\People'); //注入People这个类,People这个类依赖于Dog这个类,但是People也可以先注入,不会报错$container->bind('Dog', 'App\Http\Controllers\Dog'); //注入Dog这个类,$people = $container->make('People'); //想要用到People类,直接去取就可以了,不会关心People类在哪里echo $people->putDog();}}
这个就是人依赖狗,只要在容器(Container)里把狗这个类注入就行了。
接下来要聊下是:
Laravel 通过服务容器来管理类依赖并进行依赖注入。如果使用一个接口作为函数参数的类型提示,这个时候就需要将指定的实现绑定到接口上面。现在我们要把dog给抽象出来一个Animal。
如下:
<?phpnamespace App\Http\Controllers\User;interface Animal{public function dogCall();}
然后把注入改一下:
$container->bind('App\Http\Controllers\User\Animal', 'App\Http\Controllers\User\Dog'); //注意和以前的那个注入相比,现在我们是把实现绑定到接口上面
这个就是所谓的面向接口编程,接口可以理解为一个规范、一个约束。高层模块不直接依赖于低层模块,它们都应该依赖于抽象(指接口)。
使用依赖注入,最重要的一点好处就是有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
控制反转
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
<?php/*** 没有IoC/DI的时候,常规的A类使用C类的示例*//*** Class c*/class c{public function say(){echo 'hello';}}/*** Class a*/class a{private $c;public function __construct(){$this->c = new C(); // 实例化创建C类}public function sayC(){echo $this->c->say(); // 调用C类中的方法}}$a = new a();$a->sayC();
当有了IoC/DI的容器后,A类不再主动去创建C了,如下图所示:

而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中,如下图所示:
<?php/*** 当有了IoC/DI的容器后,a类依赖c实例注入的示例*//*** Class c*/class c{public function say(){echo 'hello';}}/*** Class a*/class a{private $c;public function setC(C $c){$this->c = $c; // 实例化创建C类}public function sayC(){echo $this->c->say(); // 调用C类中的方法}}$c = new C();$a = new a();$a->setC($c);$a->sayC();