简单归纳一下
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服务提供者还支持延迟加载,具体可参考服务提供者文档