서비스 로케이터 로케이터는 종속성 주입을 포함하는 솔루션입니다. 종속성 주입이 해결된 후 서비스 사용자와 서비스 제공자가 동일하지 않으면 사용자는 누가 서비스를 제공하는지 알아야 합니다. 서비스 로케이터는 이 부분을 분리하여 종속성의 정확성을 보장해야 합니다. 서비스 공급자는 ServiceLocator에 서비스를 등록하고(동시에 종속성을 등록함) 서비스에 사용하거나 해당 서비스의 이름이나 별칭을 알고 있으면 서비스 제공자와 사용자 모두에게 좋습니다. 사용자는 제공자가 제공하는 서비스가 무엇인지 알 필요가 있지만 서비스가 무엇에 의존하는지 알 필요는 없으며 서비스 제공자는 "사용"할 필요가 없습니다. 사용자들에게는 "랜덤으로", "서비스로 인한 버그로 인해 불편을 겪고 있습니다.
그럼 yii2는 ServiceLocator를 어떻게 사용하나요? 사실 다음과 같이 매우 간단합니다
//魔术方法, 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();
애플리케이션 확인
class Application extends \yii\base\Application //继续追踪 \yii\base\Application abstract class Application extends Module //继续追踪 Module class Module extends ServiceLocator
그렇습니다. yii2에서 사용하는 종속성 주입 및 서비스 로케이터에 대해서는 이전과 이후에 서로 연락했습니다.
위는 yii2 에세이입니다. (7) 의존성 주입 - (4) 서비스 로케이터의 내용 더 많은 관련 내용을 원하시면 결제해 주세요. PHP 중국어 웹사이트(www.php.cn)를 주목하세요!