Le localisateur de services est une solution à l'injection de dépendances. Il inclut l'injection de dépendances. Une fois l'injection de dépendances résolue, si l'utilisateur du service et le fournisseur de services ne sont pas la même personne, l'utilisateur doit savoir qui fournit le service. sont nécessaires pour garantir l'exactitude des dépendances, qui couplent les utilisateurs et les fournisseurs. Le localisateur de services dissocie cette partie. Le fournisseur de services enregistre le service dans le ServiceLocator (et enregistre les dépendances en même temps) et indique uniquement au service d'utiliser ou. les noms ou les alias de ces services, alors c'est bon pour les fournisseurs de services et les utilisateurs. Les utilisateurs ont seulement besoin de savoir quels services le fournisseur fournit, mais n'ont pas besoin de savoir de quoi ils dépendent, et les fournisseurs de services n'ont pas besoin de « utiliser ». au hasard" pour les utilisateurs. "Troublé par des bugs causés par le service.
Alors, comment yii2 utilise-t-il ServiceLocator ? En fait, c'est très simple comme suit
//魔术方法, 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){}
Alors, quand ServiceLocator s'est-il impliqué ? Continuons à ouvrir notre index.php, faites attention à la phrase suivante
(new yii\web\Application($config))->run();
Vérifions l'application
class Application extends \yii\base\Application //继续追踪 \yii\base\Application abstract class Application extends Module //继续追踪 Module class Module extends ServiceLocator
D'accord, nous nous sommes contactés avant et après, c'est tout pour l'injection de dépendances et le localisateur de services utilisés par yii2.
Ce qui précède est l'essai yii2 (7) Injection de dépendances - (4) Le contenu du localisateur de service Pour plus de contenu connexe, veuillez payer. attention au site PHP chinois (www.php.cn) !