yii2 随笔(七)依赖注入——(4)服务定位器
服务定位器定位器是依赖注入的一种解决方式,它包含依赖注入,在解决了依赖注入后,如果服务使用者和服务提供者不是用一个人,那么使用者要了解提供服务的必须参数,这样才能保证依赖的正确性,这就耦合了使用者和提供者,服务定位器就是解耦这部分的,服务提供者在 ServiceLocator 中注册服务(同时注册了依赖),仅仅告诉服务使用者那些服务的名称或者别名,那么对于服务提供者和使用者都是好的,使用者只需要知道提供者提供的什么服务,而不必知道依赖什么,服务提供者也不必为使用者“胡乱使用”服务而导致的bug所困扰。
那么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();
我们查看Application
class Application extends \yii\base\Application //继续追踪 \yii\base\Application abstract class Application extends Module //继续追踪 Module class Module extends ServiceLocator
yii 用 set[typename] 的函数来确保属性的可写性,在基类 yii\base\Object 的构造函数里使用了 Yii::configure($this, $config);这个会调用 setComponents 函数注册服务。
好啦,前后都联系上了,yii2使用的依赖注入和服务定位器,就说到这里。
以上就是yii2 随笔(七)依赖注入——(4)服务定位器的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

本篇文章带大家了解一下依赖注入,介绍一下依赖注入解决的问题和它原生的写法是什么,并聊聊Angular的依赖注入框架,希望对大家有所帮助!

在Phalcon框架中使用依赖注入(DependencyInjection)的方法引言:在现代的软件开发中,依赖注入(DependencyInjection)是一种常见的设计模式,旨在提高代码的可维护性和可测试性。而Phalcon框架作为一个快速、低耗的PHP框架,也支持使用依赖注入来管理和组织应用程序的依赖关系。本文将向您介绍如何在Phalcon框架中

yii2去掉jquery的方法:1、编辑AppAsset.php文件,注释掉变量$depends里的“yii\web\YiiAsset”值;2、编辑main.php文件,在字段“components”下面添加配置为“'yii\web\JqueryAsset' => ['js' => [],'sourcePath' => null,],”即可去掉jquery脚本。

在Go中,依赖注入(DI)模式通过函数参数传递实现,类型包括值传递和指针传递。在DI模式中,依赖项通常以指针传递,以提高解耦性、减少锁争用和支持可测试性。通过使用指针,函数与具体实现解耦,因为它只依赖于接口类型。指针传递还可以减少传递大对象的开销,从而减少锁争用。此外,DI模式可以轻松地为使用DI模式的函数编写单元测试,因为可以轻松地模拟依赖项。

针对使用JUnit测试依赖注入,摘要如下:使用模拟对象创建依赖项:@Mock注解可创建依赖项的模拟对象。设置测试数据:@Before方法在每个测试方法前运行,用于设置测试数据。配置模拟行为:Mockito.when()方法配置模拟对象的预期行为。验证结果:assertEquals()断言检查实际结果与预期值是否匹配。实际应用:可使用依赖注入框架(如SpringFramework)注入依赖项,通过JUnit单元测试验证注入的正确性和代码的正常运行。

答案:在Go语言中,依赖注入可以通过接口和结构体实现。定义一个描述依赖项行为的接口。创建一个实现该接口的结构体。在函数中通过接口作为参数注入依赖项。允许在测试或不同场景中轻松替换依赖项。

答案:PHP中的依赖注入和服务容器有助于灵活地管理依赖项,提高代码可测试性。依赖注入:通过容器传递依赖项,避免在函数内直接创建,提升灵活性。服务容器:存储依赖项实例,方便在程序中访问,进一步增强松散耦合。实战案例:示例应用程序演示依赖注入和服务容器的实际应用,将依赖项注入到控制器,体现松散耦合优势。

在Golang单元测试中使用依赖注入(DI)可以隔离要测试的代码,简化测试设置和维护。流行的DI库包括wire和go-inject,它们可以生成依赖项桩或模拟,供测试使用。DI测试的步骤包括设置依赖项、设置测试用例和断言结果。使用DI测试HTTP请求处理函数的示例表明,它可以轻松隔离和测试代码,无需实际依赖项或通信。
