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 }
时间: 2024-12-26 15:28:41

Yii源码阅读笔记(三十四)的相关文章

Yii源码阅读笔记(十四)

Model类,集中整个应用的数据和业务逻辑——场景.属性和标签: 1 /** 2 * Returns a list of scenarios and the corresponding active attributes. 3 * An active attribute is one that is subject to validation in the current scenario. 4 * 返回所有场景及与之对应的 active 属性的列表 5 * active 属性是指在默认场景中验

Yii源码阅读笔记(十二)

Action类,控制器中方法的基类: 1 namespace yii\base; 2 3 use Yii; 4 5 /** 6 * Action is the base class for all controller action classes. 7 * Action是所有控制器方法的基类 8 * Action provides a way to reuse action method code. An action method in an Action 9 * class can be

Yii源码阅读笔记(十八)

View中的查找视图文件方法和渲染文件方法 1 /** 2 * Finds the view file based on the given view name. 3 * 通过view文件名查找view文件 4 * @param string $view the view name or the path alias of the view file. Please refer to [[render()]] 5 * on how to specify this parameter. 6 * @

Yii源码阅读笔记(十五)

Model类,集中整个应用的数据和业务逻辑——验证 /** * Returns the attribute labels. * 返回属性的标签 * * Attribute labels are mainly used for display purpose. For example, given an attribute * `firstName`, we can declare a label `First Name` which is more user-friendly and can *

Yii源码阅读笔记(十六)

Model类,集中整个应用的数据和业务逻辑—— /** * Generates a user friendly attribute label based on the give attribute name. * 生成一个对用户友好的属性标签,将属性名中的下划线.破折号.点替换为空格,并且每个单词的首字母大写 * This is done by replacing underscores, dashes and dots with blanks and * changing the first

Yii源码阅读笔记(十)

控制器类,所有控制器的基类,用于调用模型和布局,输出到视图 1 namespace yii\base; 2 3 use Yii; 4 5 /** 6 * Controller is the base class for classes containing controller logic. 7 * 控制器,是所用控制器类的基类 8 * 9 * @property Module[] $modules 只读属性 当前控制器的所有模块 10 * 11 * @property string $rout

Yii源码阅读笔记(十九)

View中渲染view视图文件的前置和后置方法,以及渲染动态内容的方法: 1 /** 2 * @return string|boolean the view file currently being rendered. False if no view file is being rendered. 3 */ 4 public function getViewFile() 5 { 6 return end($this->_viewFiles);//返回[_viewFiles]中的最后一个view

Yii源码阅读笔记 - 日志组件

?使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category);Yii::trace($message, $category); 两者的区别在于后者依赖于应用开启调试模式,即定义常量YII_DEBUG: defined('YII_DEBUG') or define('YII_DEBUG', true); Yii::log方法的调用需要指定message的level和category.category是格式为“xxx.yyy.z

Yii源码阅读笔记(一)

今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于web目录的index.php,用于启动web应用和配置一些路径参数. index.php—— 1 // comment out the following two lines when deployed to production 2 defined('YII_DEBUG') or define('Y

Yii源码阅读笔记(二)

接下来阅读BaseYii.php vendor/yiisoft/yii2/Yii.php—— 1 namespace yii; 2 3 use yii\base\InvalidConfigException; 4 use yii\base\InvalidParamException; 5 use yii\base\UnknownClassException; 6 use yii\log\Logger; 7 use yii\di\Container; 第1行定义命名空间为yii: 第3到7行使用了