Yii源码阅读笔记(三十四)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Yii源码阅读笔记(三十四)相关的知识,希望对你有一定的参考价值。
Instance类, 表示依赖注入容器或服务定位器中对某一个对象的引用
1 namespace yii\di; 2 3 use Yii; 4 use yii\base\InvalidConfigException; 5 6 /** 7 * Instance represents a reference to a named object in a dependency injection (DI) container or a service locator. 8 * Instance 表示依赖注入容器或服务定位器中对某一个对象的引用 9 * 10 * You may use [[get()]] to obtain the actual object referenced by [[id]]. 11 * 可以通过使用[[get()]]方法和[[id]]获取实际对象的引用 12 * 13 * Instance is mainly used in two places: 14 * Instance 主要在两个地方被使用: 15 * 16 * - When configuring a dependency injection container, you use Instance to reference a class name, interface name 17 * or alias name. The reference can later be resolved into the actual object by the container. 18 * 在配置“依赖注入容器”时,可以使用Instance引用一个类名称、接口名称或别名。该引用将被容器将解析为实际的对象 19 * - In classes which use service locator to obtain dependent objects. 20 * 在类中使用服务定位器获取依赖对象时。 21 * 22 * The following example shows how to configure a DI container with Instance: 23 * 24 * ```php 25 * $container = new \yii\di\Container; 26 * $container->set(‘cache‘, ‘yii\caching\DbCache‘, Instance::of(‘db‘)); 27 * $container->set(‘db‘, [ 28 * ‘class‘ => ‘yii\db\Connection‘, 29 * ‘dsn‘ => ‘sqlite:path/to/file.db‘, 30 * ]); 31 * ``` 32 * 33 * And the following example shows how a class retrieves a component from a service locator: 34 * 35 * ```php 36 * class DbCache extends Cache 37 * { 38 * public $db = ‘db‘; 39 * 40 * public function init() 41 * { 42 * parent::init(); 43 * $this->db = Instance::ensure($this->db, ‘yii\db\Connection‘); 44 * } 45 * } 46 * ``` 47 * 48 * @author Qiang Xue <[email protected]> 49 * @since 2.0 50 */ 51 class Instance 52 { 53 /** 54 * @var string the component ID, class name, interface name or alias name 55 * @var string 用于保存类名、接口名或者别名 56 */ 57 public $id; 58 59 60 /** 61 * Constructor. 62 * 构造函数,仅将传入的ID赋值给 $id 属性 63 * @param string $id the component ID 64 */ 65 protected function __construct($id) 66 { 67 $this->id = $id; 68 } 69 70 /** 71 * Creates a new Instance object. 72 * 静态方法创建一个Instance实例 73 * @param string $id the component ID 74 * @return Instance the new Instance object. 75 */ 76 public static function of($id) 77 { 78 return new static($id);//实例化访问该方法的类 79 } 80 81 /** 82 * Resolves the specified reference into the actual object and makes sure it is of the specified type. 83 * 静态方法,用于将引用解析成实际的对象,并确保这个对象的类型 84 * 85 * The reference may be specified as a string or an Instance object. If the former, 86 * it will be treated as a component ID, a class/interface name or an alias, depending on the container type. 87 * 88 * If you do not specify a container, the method will first try `Yii::$app` followed by `Yii::$container`. 89 * 90 * For example, 91 * 92 * ```php 93 * use yii\db\Connection; 94 * 95 * // returns Yii::$app->db 96 * $db = Instance::ensure(‘db‘, Connection::className()); 97 * // returns an instance of Connection using the given configuration 98 * $db = Instance::ensure([‘dsn‘ => ‘sqlite:path/to/my.db‘], Connection::className()); 99 * ``` 100 * 101 * @param object|string|array|static $reference an object or a reference to the desired object. 102 * You may specify a reference in terms of a component ID or an Instance object. 103 * Starting from version 2.0.2, you may also pass in a configuration array for creating the object. 104 * If the "class" value is not specified in the configuration array, it will use the value of `$type`. 105 * @param string $type the class/interface name to be checked. If null, type check will not be performed. 106 * @param ServiceLocator|Container $container the container. This will be passed to [[get()]]. 107 * @return object the object referenced by the Instance, or `$reference` itself if it is an object. 108 * @throws InvalidConfigException if the reference is invalid 109 */ 110 public static function ensure($reference, $type = null, $container = null) 111 { 112 if (is_array($reference)) {//如果$reference是数组 113 $class = isset($reference[‘class‘]) ? $reference[‘class‘] : $type;//$reference中有类名,则将类名赋值给$class,否则将$type赋值给$class 114 if (!$container instanceof Container) {//如果$container不是Container的实例 115 $container = Yii::$container;//则取Yii中定义的Container对象 116 } 117 unset($reference[‘class‘]); 118 return $container->get($class, [], $reference);//返回引用的实例 119 } elseif (empty($reference)) {//如果$reference为空,则抛出异常 120 throw new InvalidConfigException(‘The required component is not specified.‘); 121 } 122 123 if (is_string($reference)) {//如果$reference是字符串 124 $reference = new static($reference);//则实例化该引用类 125 } elseif ($type === null || $reference instanceof $type) {//如果给定检查的类为空或者$reference是给定检查的类的实例 126 return $reference;//返回该实例 127 } 128 129 if ($reference instanceof self) {//如果$reference是Istance的实例 130 $component = $reference->get($container);//则获取调用$container的组件的对象 131 if ($type === null || $component instanceof $type) {//如果给定检查的类为空或者$component是给定检查的类的实例 132 return $component;//返回$component 133 } else {//否则抛出异常 跟预期的类型不符合 134 throw new InvalidConfigException(‘"‘ . $reference->id . ‘" refers to a ‘ . get_class($component) . " component. $type is expected."); 135 } 136 } 137 138 $valueType = is_object($reference) ? get_class($reference) : gettype($reference); 139 throw new InvalidConfigException("Invalid data type: $valueType. $type is expected."); 140 } 141 142 /** 143 * Returns the actual object referenced by this Instance object. 144 * 获取这个实例所引用的实际对象,它调用的是yii\di\Container::get()来获取实际对象 145 * @param ServiceLocator|Container $container the container used to locate the referenced object. 146 * If null, the method will first try `Yii::$app` then `Yii::$container`. 147 * @return object the actual object referenced by this Instance object. 148 */ 149 public function get($container = null) 150 { 151 if ($container) { 152 return $container->get($this->id);//如果传入$container容器,则调用$container中的get方法获取引用的实际对象 153 } 154 if (Yii::$app && Yii::$app->has($this->id)) {//如果该对象已有实例 155 return Yii::$app->get($this->id);//返回该实例 156 } else { 157 return Yii::$container->get($this->id);//否则调用yii\di\Container::get()来获取实际对象 158 } 159 } 160 }
以上是关于Yii源码阅读笔记(三十四)的主要内容,如果未能解决你的问题,请参考以下文章