依赖注入
laravel依赖注入是A类在依赖B类时,可以直接在容器中直接注入B类和A类,容器会自己去寻找依赖,而不用担心A类和B类谁先注入到容器。
新建立两个文件(注意这两个文件的namespace),一个是:
<?php
namespace 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();
}
}
另一个是:
<?php
namespace App\Http\Controllers\User;
class Dog
{
public function dogCall(){
return '汪汪汪';
}
}
在route中建立一条路由:
Route::get('user/test', 'User\UserController@test');
最后建立一个contorller
<?php
namespace 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。
如下:
<?php
namespace 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();