关于laravel服务(容器)和服务提供者及绑定
Laravel 服务容器是一个用于管理类依赖和执行依赖注入的强大工具。
参考:https://laravelacademy.org/post/9534.html
<?php
namespace App\Http\Controllers\UcServer;
use App\Http\Controllers\Controller;
use App\RepositoryInterface\UcenterRepositoryInterface;
use App\Traits\Controller\AjaxTraits;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function wxEncryptedLogin(Request $request, UcenterRepositoryInterface $ucenterRepository){
...
$decryptData = $ucenterRepository->decryptData($appId, $sessionKey, $encryptedData, $iv);
...
}
}
在这个控制器的wxEncryptedLogin方法中,传入两个参数,$request 和 $ucenterRepository。
$request是包含请求的实例。
$ucenterRepository是实现了UcenterRepositoryInterface接口的一个类的实例。
其中,$request已经很明确了,通过namespace和autoload,laravel会自动加载Illuminate\Http\Request的实例,而实现
了UcenterRepositoryInterface接口的类可能不止一个,于是我们需要做额外的绑定,这个需要服务提供者ServiceProviders来做。
在laravel框架的bootstrap/app.php中默认已加载了三个,当然自己可以再注册其他provider。
$app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
$app->register(App\Providers\EventServiceProvider::class);
每一个都可以提供一类功能,其中“绑定功能”是由AppServiceProvider提供的,我们打开AppServiceProvider类,在register方法
中来实现绑定。
public function register()
{
// 1、接口绑定到实现
$this->app->bind('App\RepositoryInterface\UcenterRepositoryInterface', 'App\Repository\UcenterRepository');
// 2、绑定到单例,传参
$this->app->singleton('Ip2Region', function ($app) {
return new Ip2Region(base_path('app/Support/Ip2region/data/ip2region.db'));
});
// 3、绑定到实例
$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\API', $api);
}
通过以上的例子,我们再次来梳理“服务”,“服务容器”,“服务提供者”三者的关系:
1、Laravel通过依赖注入(DI)的方式来实现控制反转(IOC),而普通对象的依赖注入的实现很简单,只需要利用反射的原理即可,那么复杂的依赖注入,比如,要求注入的对象需要经过带参数实例化的,或者需要初始化后再传入的,或者某个接口的一个实现(假如该接口有多个实现类)。这样的话,就需要为依赖注入这个操作提供给开发者一个可灵活配置来降低耦合度的地方,于是Laravel就提供了服务容器,在容器里里告诉Laravel你要注入的实例是啥样的。
Laravel提示:
{tip} 如果类没有依赖任何接口,就没有必要将类绑定到容器中。容器不需要指定如何构建这些对象,因为它可以使用反射自动解析这些对象。其实说的就是普通的依赖注入!
2、服务(具体注入的实例);
服务容器(代理作用,比如一个接口协议,将调用与实现解耦,在这里将代理与具体实现绑定起来);
服务提供者(服务容器的大致分组,你可以将一个服务容器放在某一个服务提供者里面)。
3、自建服务的步骤:
创建服务类;
设置服务容器,就是一个名称;
创建服务提供者Provider,然后需要将这个Provider添加到 config/app.php 文件的 providers 数组下面,这样框架就黑替你注册服务了;或者使用其他Provider,在Provider中将服务与容器绑定;
4、使用服务
我们绑定了服务容器之后,就可以使用这个容器提供的服务了,可以使用
$api = $this->app->make(‘HelpSpot\API’);
如果你的代码处于无法访问 $app 变量的位置,则可用全局辅助函数 resolve 来解析:
$api = resolve(‘HelpSpot\API’);
有时候我们使用 Facades 的时候,是不知道这个服务容器指向的服务是哪个,就可以将服务容器解析出来查看。