标签:
今天来看Container.php,yii2的容器代码。
<?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace yii\di; use ReflectionClass; use yii\base\Component; use yii\base\InvalidConfigException; /** * Container implements a [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) container. * 实现了依赖注入容器(http://en.wikipedia.org/wiki/dependency_injection)。 * A dependency injection (DI) container is an object that knows how to instantiate and configure objects and * all their dependent objects. * 依赖注入(DI)的容器是一个对象,知道如何实例化和配置所有的依赖对象。 * For more information about DI, please refer to * 有关更多信息,请参阅 * [Martin Fowler‘s article](http://martinfowler.com/articles/injection.html). * * Container supports constructor injection as well as property injection. * 容器支持构造函数注入以及属性注入。 * To use Container, you first need to set up the class dependencies by calling [[set()]]. * 使用的容器,你首先需要设置类的依赖关系,通过调用[[set()]]方法。 * You then call [[get()]] to create a new class object. * 然后你可以调用[[get()]]方法创建一个新的类的对象。 * Container will automatically instantiate * dependent objects, inject them into the object being created, configure and finally return the newly created object. * 容器会自动实例化依赖对象,将它们注入到正在创建的对象中,配置并最终返回新创建的对象。 * @property array $definitions The list of the object definitions or the loaded shared objects (type or ID => * definition or instance). This property is read-only. * * @author Qiang Xue <qiang.xue@gmail.com> * @since 2.0 */ class Container extends Component { /** * @var array singleton objects indexed by their types * 用于保存单例Singleton对象,以对象类型为键 */ private $_singletons = []; /** * @var array object definitions indexed by their types * 用于保存依赖的定义,以对象类型为键 */ private $_definitions = []; /** * @var array constructor parameters indexed by object types * 用于保存构造函数的参数,以对象类型为键 */ private $_params = []; /** * @var array cached ReflectionClass objects indexed by class/interface names * 用于缓存ReflectionClass对象,以类名或接口名为键 */ private $_reflections = []; /** * @var array cached dependencies indexed by class/interface names. Each class name * is associated with a list of constructor parameter types or default values. * 用于缓存依赖信息,以类名或接口名为键 */ private $_dependencies = []; /** * Returns an instance of the requested class. * 返回所请求的类的实例。 * You may provide constructor parameters (`$params`) and object configurations (`$config`) * that will be used during the creation of the instance. * 你可以提供构造函数参数(` $params `)和对象的配置(`$config`),在创建实例时使用。 * Note that if the class is declared to be singleton by calling [[setSingleton()]], * 注意,如果类声明为单称[[setsingleton()]], * the same instance of the class will be returned each time this method is called. * 每次调用该方法时,该类的同一实例将被返回。 * In this case, the constructor parameters and object configurations will be used * only if the class is instantiated the first time. * 在这种情况下,只有当类被实例化的第一时间,将使用构造函数参数和对象配置. * @param string $class the class name or an alias name (e.g. `foo`) that was previously registered via [[set()]] * or [[setSingleton()]]. * @param array $params a list of constructor parameter values. The parameters should be provided in the order * they appear in the constructor declaration. If you want to skip some parameters, you should index the remaining * ones with the integers that represent their positions in the constructor parameter list. * @param array $config a list of name-value pairs that will be used to initialize the object properties. * @return object an instance of the requested class. * @throws InvalidConfigException if the class cannot be recognized or correspond to an invalid definition */ public function get($class, $params = [], $config = []) { if (isset($this->_singletons[$class])) { // singleton // 如果Singleton对象的数组中有,就直接返回 return $this->_singletons[$class]; } elseif (!isset($this->_definitions[$class])) { // 如果定义的数组中没有,就去构建它 return $this->build($class, $params, $config); } $definition = $this->_definitions[$class]; if (is_callable($definition, true)) { // 如果$definition是callable,就先将参数合并,再将其中的Instance实例替换掉 $params = $this->resolveDependencies($this->mergeParams($class, $params)); // 调用$definition $object = call_user_func($definition, $this, $params, $config); } elseif (is_array($definition)) { // 如果是一个数组 $concrete = $definition[‘class‘]; unset($definition[‘class‘]); // 合并配置和参数 $config = array_merge($definition, $config); $params = $this->mergeParams($class, $params); if ($concrete === $class) { $object = $this->build($class, $params, $config); } else { $object = $this->get($concrete, $params, $config); } } elseif (is_object($definition)) { // 如果$definition是个对象,就直接保存到_singletons中 return $this->_singletons[$class] = $definition; } else { throw new InvalidConfigException("Unexpected object definition type: " . gettype($definition)); } if (array_key_exists($class, $this->_singletons)) { // singleton // 如果_singletons中没有这个类的实例,就保存一份 $this->_singletons[$class] = $object; } return $object; }
标签:
原文地址:http://www.cnblogs.com/taokai/p/5470322.html