PHP 服务容器(资料聚合)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 实现容器
// DB 类 Session 类 FileSystem 类 省略

class Container{
public $bindings;
/**
* 将 闭包 与 别名 对应起来,和注册树模式差不多
*/
public function bind($abstract,$concrete){
$this->bindings[$abstract]=$concrete;
}

// 调用
public function make($abstract,$parameters=[]){
return call_user_func_array($this->bindings[$abstract],$parameters);
// 参数传入 回调函数,完成类实例化(返回的是一个对象,即类的实例)
}
}

// 服务注册

$container=new Container();

$container->bind('db',function($arg1,$arg2){
// 回调函数中实例化类,即返回对象
return new DB($arg1,$arg2);
});

$container->bind('session',function($arg1,$arg2){
return new Session($arg1,$arg2);
});

$container->bind('fs',function($arg1,$arg2){
return new FileSystem($arg1,$arg2);
});

// 容器依赖

class Writer{
protected $_db;
protected $_filesystem;
protected $_session;
protected $container;
public function Writer(Container $container){
// 将对象赋值给对象属性
$this->_db=$container->make('db',[1,2]);
$this->_filesystem=$container->make('session',[3,4]);
$this->_session=$container->make('fs',[5,6]);
}
}

$writer=new Writer($container);

依赖注入

依赖注入是通过类的构造函数、方法、或者直接写入的方式,将所依赖的组件传递给类的方式。

1
2
3
4
5
6
7
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
}
1
2
3
4
5
6
7
class User
{
function setSessionStorage($storage)
{
$this->storage = $storage;
}
}
1
2
3
4
5
6
class User
{
public $sessionStorage;
}

$user->sessionStorage = $storage;

只要不是由内部生产(比如初始化、构造函数中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于 依赖注入(DI)

根据经验,一般通过构造函数注入的是强依赖关系的组件,setter 方式用来注入可选的依赖组件。

反转

所谓的反转,主要指由 主动依赖 到 被动依赖 。

1
2
3
4
5
6
7
8
9
//主动依赖
function __construct() {
$this->user = new UserModel();
}

//被动依赖
function __construct(UserModel $user) {
$this->user = $user;
}

Links

0%