时间:2021-07-01 10:21:17 帮助过:5人阅读
//魔术方法, public function __get($name){ //得到某个注册的方法 if ($this->has($name)) { return $this->get($name); } else { return parent::__get($name); } } //魔术方法查看某个服务是否存在,源码略 public function __isset($name){} //__isset()中调用,查看某个服务是否存在,源码略 public function has($id, $checkInstance = false){} //得到某个服务 public function get($id, $throwException = true) { if (isset($this->_components[$id])) {//如果是已经处理的服务,就直接返回 return $this->_components[$id]; } if (isset($this->_definitions[$id])) {//如定义了该服务 $definition = $this->_definitions[$id];//得到服务的定义 //如果服务是一个闭包,则把闭包注册到已经实例化的服务中,并且返回闭包 if (is_object($definition) && !$definition instanceof Closure) { return $this->_components[$id] = $definition; } else {//其他的情况下通过依赖注入生成对象,并且注册为已处理,返回对象 return $this->_components[$id] = Yii::createObject($definition); } } elseif ($throwException) {//如果抛出异常,则抛出异常 throw new InvalidConfigException("Unknown component ID: $id"); } else {//其他返回null return null; } } //注册一个服务 public function set($id, $definition) { if ($definition === null) {//如果该服务的定义为null,则删除已经实例化的服务,返回空,用于注销已经实例化的并且保存过的服务的定义 unset($this->_components[$id], $this->_definitions[$id]); return; } //清空已经实例化的服务 unset($this->_components[$id]); //如果该服务的定义为一个对象,并且是一个可调用的结构 if (is_object($definition) || is_callable($definition, true)) { // an object, a class name, or a PHP callable $this->_definitions[$id] = $definition; } elseif (is_array($definition)) {//如果该服务是一个配置数组 // a configuration array if (isset($definition['class'])) {//如果有class键值,则直接注册为一个服务的定义 $this->_definitions[$id] = $definition; } else {//是配置数组,但是没有指定class,则抛出异常 throw new InvalidConfigException("The configuration for the \"$id\" component must contain a \"class\" element."); } } else {//什么都不是,抛出异常,非法注册服务 throw new InvalidConfigException("Unexpected configuration type for the \"$id\" component: " . gettype($definition)); } } //清空已经实例化过的服务和定义,代码略 public function clear($id){} //得到已经实例化后的服务,或者得到可用的服务配置 public function getComponents($returnDefinitions = true){} //注册所有的服务,这里的$components,就是你在config里写的 $config['components']值 public function setComponents($components){}
那么ServiceLocator是从什么时候介入的呢?我们继续开我们的index.php,注意下面那句话
(new yii\web\Application($config))->run();
我们查看Application
class Application extends \yii\base\Application //继续追踪 \yii\base\Application abstract class Application extends Module //继续追踪 Module class Module extends ServiceLocator哈,终于找到丫了!!!我们的application 其实就一个服务定位器,我们在配置文件里配置的components,都是application的这个服务定位器注册的服务。这下知道为什么叫做 setComponents这个函数了吧,不明白继续往下看。
好啦,前后都联系上了,yii2使用的依赖注入和服务定位器,就说到这里。
以上就是yii2 随笔(七)依赖注入——(4)服务定位器的内容,更多相关内容请关注PHP中文网(www.gxlcms.com)!