理解服务容器和服务提供者
原文链接:https://learnku.com/articles/12852/laravel-service-provider-guide
什么是服务容器和服务提供者
服务容器用于:
- 管理类的依赖
- 执行依赖注入
服务提供者用于将服务绑定到服务容器(register
)
过程
-
配置文件:
config/app.php
,用来告诉laravel有哪些服务提供者。如下:我们定义App\Providers\EnvatoCustomServiceProvider::class
'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Notifications\NotificationServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, /* * Package Service Providers... */ /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, App\Providers\EnvatoCustomServiceProvider::class, ],
-
实现服务提供者
App\Providers\EnvatoCustomServiceProvider
<?php namespace App\Providers; use App\Library\Services\DemoOne; use App\Library\Services\DemoTwo; use Illuminate\Support\ServiceProvider; class EnvatoCustomServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { $this->app->bind('App\Library\Services\Contracts\CustomServiceInterface', function ($app) { return new DemoTwo(); }); } /** * Bootstrap services. * * @return void */ public function boot() { // } }
我们看到,
register
将App\Library\Services\Contracts\CustomServiceInterface
和new DemoTwo()
对应关系告知到$this->app
,绑定好了之后,当框架要使用new DemoTwo()
时可以不用直接实例化或者反射机制,而是通过在容器中CustomServiceInterface
与new DemoTwo()
的对应关系来找到实例。如果业务需要替换到
DemoOne()
,在服务提供者EnvatoCustomServiceProvider
的register
方法中修改return new DemoTwo();
,从而实现了解耦。如果我们的依赖无需任何接口,则无需将类绑定到容器。容器此时不需要了解创建对象的具体细节,而可以通过反射功能实现自动注入。
<?php /** * Created by PhpStorm. * User: 12179 * Date: 2020/5/14 * Time: 16:26 */ namespace App\Library\Services\Contracts; Interface CustomServiceInterface { public function doSomethingUseful(); }
<?php /** * Created by PhpStorm. * User: 12179 * Date: 2020/5/14 * Time: 16:21 */ namespace App\Library\Services; use App\Library\Services\Contracts\CustomServiceInterface; class DemoTwo implements CustomServiceInterface { public function doSomethingUseful() { return 'Output from DemoTwo'; } }
-
使用,在控制器中就可以直接使用依赖注入的方式,框架会通过服务容器找到
new DemoTwo()
public function demo(CustomServiceInterface $customService) { echo $customService->doSomethingUseful(); }
-
bind
方法中能获取所有通过服务提供者注册到容器中的服务。通常,你会在这个方法中注册某些功能完成后需要触发其它操作的事件监听器。public function boot() { View::share('key', 'value'); //创建一些共享数据,前台模板可以使用{{$key}}获取到value }