Service Provider 测试实例

简单归纳一下

1、服务类继承契约接口(为了对类的定义加以约束)

2、创建服务提供者(Service Provider)

3、在服务提供者的register内绑定服务类

4、注册服务提供者到config

5、创建服务容器(Service Container

6、将服务提供者依赖注入服务容器

7、服务容器使用该服务

1、定义服务类

有了上一节有关服务容器的讲述,理解起服务提供者来很简单。我们这里先定义一个绑定到容器的测试类TestService,为了对类的定义加以约束,我们同时还定义一个契约接口TestContract。

定义TestContract如下:

1
2
3
4
5
6
7
8
<?php
 
namespace App\Contracts;
 
interface TestContract
{
    public function callMe($controller);
}

定义TestService如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
 
namespace App\Services;
 
use App\Contracts\TestContract;
 
class TestService implements TestContract
{
    public function callMe($controller)
    {
        dd('Call Me From TestServiceProvider In '.$controller);
    }
}

2、创建服务提供者

接下来我们定义一个服务提供者TestServiceProvider用于注册该类到容器。创建服务提供者可以使用如下Artisan命令:

1
php artisan make:provider TestServiceProvider

该命令会在app/Providers目录下生成一个TestServiceProvider.php文件,我们编辑该文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
 
namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
use App\Services\TestService;
 
class TestServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
 
    /**
     * Register the application services.
     *
     * @return void
     * @author LaravelAcademy.org
     */
    public function register()
    {
        //使用singleton绑定单例
        $this->app->singleton('test',function(){
            return new TestService();
        });
 
        //使用bind绑定实例到接口以便依赖注入
        $this->app->bind('App\Contracts\TestContract',function(){
            return new TestService();
        });
    }
}

可以看到我们使用了两种绑定方法,更多绑定方法参考服务容器文档。

3、注册服务提供者

定义完服务提供者类后,接下来我们需要将该服务提供者注册到应用中,很简单,只需将该类追加到配置文件config/app.php的providers数组中即可:

1
2
3
4
5
6
'providers' => [
 
    //其他服务提供者
 
    App\Providers\TestServiceProvider::class,
],

4、测试服务提供者

这样我们就可以在应用中使用该服务提供者了,为了测试该服务提供者我们首先使用Artisan命令创建一个资源控制器TestController:

1
php artisan make:controller TestController

然后在路由配置文件routes.php中定义路由:

1
Route::resource('test','TestController');

最后去TestController中编写测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
use App\Http\Requests;
use App\Http\Controllers\Controller;
 
use App;
use App\Contracts\TestContract;
 
class TestController extends Controller
{
    //依赖注入
    public function __construct(TestContract $test){
        $this->test = $test;
    }
 
    /**
     * Display a listing of the resource.
     *
     * @return Response
     * @author LaravelAcademy.org
     */
    public function index()
    {
        // $test = App::make('test');
        // $test->callMe('TestController');
        $this->test->callMe('TestController');
    }
 
    ...//其他控制器动作
}

然后我们去浏览器中访问http://laravel.app:8000/test

分别测试使用App::make和依赖注入解析绑定类调用callMe方法的输出,结果一样,都是:

1
"Call Me From TestServiceProvider In TestController"

好了,大功告成,是不是很简单?!

此外,Laravel服务提供者还支持延迟加载,具体可参考服务提供者文档