# 容器
## 简介
容器(Container)一般是一种单例模式的实现方法,具体来说就是定义一个静态成员变量(属性),用于储存实例,第一次调用时实例化一个实例,后面调用直接提取该实例,不需要重复实例化。一是可以快速获得对应的对象,减少加载时间;二是可以保持实例的状态,重新创建会丢失原有状态,非常不方便。Laravel等常见框架都是使用容器来协作的,可见其重要程度。
## 实现原理
TarBlog的容器使用一个Manager类作为管理类,该类会将其自身实例保存在$_instance静态成员变量中,需要时调出。而其他的容器则用一个$_instances成员变量来储存,并配合$_bindings和$_alias来储存对应的别名。一般而言,启动器中会调用addContainerBinding方法进行别名绑定,绑定后可以在程序任意一处调用make方法来调用实例。此外,通过PHP的反射,可以侦测到构造函数的参数类型,若类型为系统中已经绑定的类,则进行注入。
## 成员变量说明
### $_instance
管理器自己的实例
### $_bindings
记录别名绑定的类名
### $_alias
记录类绑定的别名
### $_instances
记录别名绑定的实例
## 成员方法说明
### 构造函数(无参数)
绑定自己为app(别名)实例
### getInstance
获取容器管理类实例
### addContainerBinding($name, $class)
添加名称绑定,也就是分别记录$this->_bindings和$this->_alias,但是不会马上实例化
### bidingInstance($name, $instance)
添加或更改指定名称实例,这里是修改了$this->_instances,即我们没有通过容器管理器实例化一个类,但是我们可以手动绑定这个实例对象进去。
### make($name, ...)
获取别名对应的实例。传入的参数第一个为别名,第二个开始为对应类的构造函数。利用自动注入机制,可以将已绑定的类自动注入到指定类型的参数,但是它们必须在参数列表开头。