摘要:看起来很麻烦是吧,完全可以封装一个函数,直接调用就可以了,没有必要自定义服务提供者创建契约。将自定义的服务提供者做如下修改修改了契约的绑定,所有使用契约进行依赖注入的实例,都会由实例切换到实例。
导语
laravel 的服务提供者,是框架的核心,提供了路由、日志、缓存等功能。这里要实现的需求是使用第三方 API 获取天气情况,涉及到服务提供者、契约、依赖注入等方面。相关内容可以通过下方参考资料进行了解,本文内容不进行展开介绍,代码可查看 GitHub。
创建服务提供者可以使用 artisan 快捷的创建服务提供者,执行 php artisan make:provider WeatherServiceProvider 即在 app/Providers 目录下创建了 WeatherServiceProvider.php 文件;
在 config/app.php 中注册服务提供者,在 providers 数组中将创建的服务提供者 AppProvidersWeatherServiceProvider::class, 写入,如下
创建契约在 app 目录下新建 Contracts 目录用以存放契约文件;
在 app/Contracts 目录下创建契约,即 Weather.php 接口文件。在接口中只定义了 public function getWeather($cityName); 一个方法用于获取天气信息;
实现契约在 app 目录下新建 Service/Weather 目录用于存放实现 Weather.php 契约的文件;
选择一个第三方的天气 API 来实现契约。这里使用的是心知天气。关于 API 的调用,可以查看文档;
最终创建的文件是 app/Service/Weather/Xinzhi.php。继承了 Weather.php 接口文件,所有要实现 getWeather 方法,代码可查看 GitHub;
这里先埋个伏笔。除了上面的 Xinzhi.php,另外选择和风天气实现契约,文件为 app/Service/Weather/Hefeng.php。代码查看 GitHub;
服务提供者绑定我们已经实现了契约,接下来就是绑定具体实现类。回到开始创建的服务提供者,在 register 方法中添加如下代码
$this->app->bind("AppContractsWeather", function() { return new Xinzhi(); });
最后就可以正常使用了。新建路由,然后测试。试下通过依赖注入调用
public function getWeather(Request $request, Weather $weather) { return $weather->getWeather($request->input("city", "beijing")); }
没有问题
解耦完成上述所有步骤,这个需求已经实现了。看起来很麻烦是吧,完全可以封装一个函数,直接调用就可以了,没有必要自定义服务提供者、创建契约。实际上述步骤,其中的一个目的就是小标题那两个字——解耦。
假设一下,我们需要在很多代码中使用这个功能,突然有一天,这个 API 挂了,怎么办?四处去查找、检查代码,然后再去修改,同时要注意参数、返回值等。光是听起来就很烦了。这个时候,如果我们的代码按照上述的步骤进行开发,解决方法就大不相同了。简而言之,一行代码就可以搞定。
还记得上面那个伏笔吧,一共有两个实例实现了接口。将自定义的服务提供者 register 做如下修改
$this->app->bind("AppContractsWeather", function() { // return new Xinzhi(); return new Hefeng(); });
修改了契约的绑定,所有使用 Weather 契约进行依赖注入的实例,都会由 Xinzhi.php 实例切换到 Hefeng.php 实例。
契约当然不止解耦这一个作用,代码更容易理解、更方便维护,甚至可以当做简明的开发文档。更多的深入理解,请查看下方参考资料。
参考资料:底层原理 —— 服务提供者、底层原理 —— 契约(Contracts)、Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)、 Laravel 从学徒到工匠系列 依赖注入篇。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/31188.html
摘要:组件扩展通常有两种方法向容器中绑定自己的接口实现痛过使用工厂模式实现的类注册自己的扩展。类库管理类以工厂模式实现,负责诸如缓存等驱动的实例化。闭包须要传入继承自和容器的实例化对象。当完成扩展之后要记住中替换成自己的扩展名称。 声明:本文并非博主原创,而是来自对《Laravel 4 From Apprentice to Artisan》阅读的翻译和理解,当然也不是原汁原味的翻译,能保证9...
摘要:今天我来分享中层关于请求响应与表单验证的知识。手动创建验证请求之前的内容是直接使用的方法来实现表单验证。下一步到这篇为止,我完成了入门指南核心概念层的路由中间件控制器请求响应表单验证的学习和整理。 showImg(https://segmentfault.com/img/remote/1460000010882838); 今天我来分享 Laravel 中 HTTP 层关于请求、响应与表...
摘要:初步尝试既然最常见的注册命令的方式是修改类中的,那么一般正常人都会从这边开始下手。又要自己取出实例,又要自己调用方法,调用方法之前还有自己先把实例化这么繁琐,肯定不是运行时添加命令的最佳实践,所以我决定继续寻找更优解。 本文首发于我的博客,原文链接:https://blessing.studio/best-... 虽然 Laravel 官方文档提供的添加 Artisan Command...
摘要:在服务提供者内部,这个工作被称之为服务容器绑定,绑定处理由服务提供者完成。通过服务提供者绑定服务是服务容器绑定服务的正确打开方式。为了完成注册服务提供者的功能,仅需要将类名加入到配置文件的节点。此时,仅需简单的调整下服务提供者中的代码。 这是一篇翻译文章,译文首发于 Laravel 服务提供者指南,转载请注明出处。 如果你使用过 Laravel 框架的话,那么,你不可能没听说过服务容器...
摘要:有一种机制来定义和执行每个服务的初始处理,实现初始处理的类称为服务提供者。在里面,要自定一个服务提供者非常容易,只要继承这个类即可。这个注册的过程其实就是前面说的实例化服务提供者的类,并调用方法的过程。 前言 上一篇博客文章收集了关于Laravel服务容器的相关知识(传送门),我们知道了服务容器主要有绑定和解析两个重要功能,那么Laravel这个框架集齐了如此多功能,我们项目可能还...
阅读 808·2021-11-25 09:43
阅读 1672·2021-09-29 09:42
阅读 1892·2019-08-30 15:55
阅读 3413·2019-08-30 15:54
阅读 2617·2019-08-30 13:20
阅读 3500·2019-08-29 13:25
阅读 907·2019-08-28 18:03
阅读 1777·2019-08-26 13:44