laravel中的服务提供者有什么作用?
第一步:定义契约接口类
<?php
namespace App\Contracts;
interface TestContract
{
public function say($info):string;
}
第二步:定义子类服务实现接口
<?php
namespace App\Services;
use App\Contracts\TestContract;
class TestService implements TestContract
{
public function say($info):string
{
dd($info);
}
}
第三步:创建服务提供者
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\TestService;
class TestServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('App\Contracts\TestContract', function(){
return new TestService();
});
}
public function boot()
{
}
}
第四步:注册服务提供者
// app\config\app.php
<?php
'providers' => [
# 此处省略其它内容
App\Providers\TestServiceProvider::class,
],
第五步:测试服务提供者
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Contracts\TestContract;
class TestController extends Controller
{
public function test(TestContract $test)
{
$test->say('test');
}
}
以上内容是按照laravel文档创建的,但是测试的时候,第三步和第四步可有可无,不注册服务提供者,在第五步的控制器中也能调用say()方法;那请问这个服务提供者到底有什么作用啊??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
服务提供者更多的是用于对于 Laravel 框架的扩展,因为在日常的项目开发过程中,我们总会遇到一些,通用性的内容,比如跨域处理、文件上传、消息推送、发送短信等,这些可以独立于项目的组件。
如果按照传统的不分离的形式,你就需要在 app 创建一个目录来保存这些内容,并且,这些可能都会有各自的配置项,那你就还需要创建对应的配置文件,现在你只需要调用 App 命令空间下对应的类,就可以调用这些服务。
但是,如果你要新建一个项目,你现在就只有把当前的代码拷贝一份出去(别忘了配置项),到新项目,然后复用,这是最理想的状态。
但是你想一下,如果因为某个功能,你修改了这个类,然后其他项目又用不到,那拷贝的时候,可能还要清理掉这些内容,又或者,这个类里面有个 BUG ,你就要修改每一个项目。
而现代化开发,讲究的就是一个复用,提高代码的复用性,减少重复(CV)工作。
现在换个方式,你可以创建一个 composer 包,然后把所有代码都搬到这个包里面去,包括配置项。然后把这个 composer 包发布到仓库去(可以自建、也可以使用公共仓库),紧接着,你就可以使用
composer require
来安装你新提取出去的这个包了。安装完成后,你的新包可能并不能完好的工作,比如提到的契约接口注册、配置项获取等。因为这会儿他只是一个普通的包。
现在,做一件事情,创建一个 ServiceProvider ,就把所有的资产(契约接口注册、配置项注册、本地化、模板)等进行注册。
然后,你还需要在 laravel 中去注册这个 ServiceProvider ,然后你得扩展包里面的内容就可以正常工作了,以后新建项目的时候,只需要 composer require 一下这个包,然后注册一下 ServiceProvider 就可以了,如果某个类有 BUG ,你现在只需要修改这个包的代码,在其他项目更新一下,即可拿到最新的代码。
注:自 laravel 5.5 起,composer 包可以配置自动注册发现服务提供者,不再需要手动去注册,变得更爽了
说到这里,或许你能理解一些,但是这大部分的功劳仍然归功于 composer ,而服务提供者(ServiceProvider) 更像是一个清单文件,来告诉 Laravel ,应该怎么处理这些资源,或者启动哪些服务。
简单的项目中,一般并不太需要自行创建 ServiceProdiver ,因为你可以简单的在自带的 AppServiceProvier 中编写你的代码,创建单独的服务提供者可以为了以后扩展打下基础。
你上面说到的契约接口注册绑定,只是服务提供者的冰山一角,可以参考文档中关于 扩展包开发 章节的内容。
关于为什么需要接口绑定,可以继续查阅有关:依赖注入、依赖倒置 方面的知识。
我理解这两个概念,倒不会纠结你这个输出结果,我会从概念的含义和场景来解释。
契约:是一组接口(interface),它们由框架提供并定义了核心服务。场景:mem切换成redis
,感觉契约类似工厂模式,方便对象的切换
服务提供者:我理解为管理服务的,注册(绑定)服务。用容器来实现,也就是依赖注入。用来解耦的。
你的第一、二步是契约,第三步是服务提供者的绑定(不是契约),第四步是契约和服务提供者都会用到的配置,第五步是一个控制器的依赖注入。如果第五步使用app()->make的方式来注入,三、四可能就需要了。感觉把契约、服务提供者、依赖注入混在一起了,我觉得分开来写比较好
最后,我也是初学者,也不知道对不对
把provider理解成插件的入口.
你这儿没效果是因为 laravel 创建对象时, 默认就是直接new,
即
app()->make('全\类名')
相当于new 全\类名
,如果你的类有个性化初始化需求, 那只能在通过provider的register设置.
比如要设置某个属性,
new TestService()->setXXX()