服務提供者
- 撰寫服務提供者
- 註冊方法
- bindings 和singletons的特性
- 引導方法
- 註冊服務提供者
服務提供者
簡介服務提供者是所有Laravel 應用程式的引導中心。你的應用程序,以及 透過伺服器引導的 Laravel 核心服務都是透過服務提供者引導。 但是,「引導」是什麼意思呢?通常,我們的可以理解為註冊,例如註冊服務容器綁定,事件監聽器,中間件,甚至是路由。服務提供者是配置應用程式的中心。
當你開啟 Laravel 的config/app.php
這篇文章你將會學到如何寫自己的服務提供者,並將其註冊到你的Laravel 應用程式中編寫服務提供者所有的服務提供者都會繼承檔案時,你會看到
providers陣列。陣列中的內容是應用程式要載入的所有服務提供者的類別。當然,其中有很多 “延遲” 提供者,他們並不會在每次請求的時候都加載,只有他們的服務實際被需要時才會加載。
Illuminate\Support\ServiceProvider
使用Artisan 命令列工具,透過類別。大多數服務提供者都包含一個
register和一個
boot方法。在
register方法中, 你只需要將事物綁定到服務容器。而不要嘗試在
register方法中註冊任何監聽器,路由,或其他任何功能
make:provider
命令可以產生一個新的提供者:
php artisan make:provider RiakServiceProvider
註冊方法如上所述,在register
讓我們來看一個基礎的服務提供者。在任何服務提供者方法中,你總是透過方法中,你只需要將服務綁定到服務容器。而不要嘗試在
register方法中註冊任何監聽器,路由,或其他任何功能。否則,你可能會意外地使用到尚未載入的服務提供者提供的服務。
$app
屬性來存取服務容器:
<?php namespace App\Providers;use Riak\Connection; use Illuminate\Support\ServiceProvider; class RiakServiceProvider extends ServiceProvider{ /** * 在服务容器里注册 * * @return void */ public function register() { $this->app->singleton(Connection::class, function ($app) { return new Connection(config('riak')); }); } }
這個服務容器只是定義了一個register
方法,並且使用該這個方法在服務容器中定義了一個
Riak\Connection介面。如果你不理解服務容器的工作原理,請查看其文件。
bindings
和singletons
的特性如果你的服務提供者註冊了許多簡單的綁定,你可能會想用
bindings
和singletons
屬性取代手動註冊每個容器綁定。當服務提供器被框架載入時,將自動檢查這些屬性並註冊對應的綁定<?php namespace App\Providers; use App\Contracts\ServerProvider; use App\Contracts\DowntimeNotifier; use Illuminate\Support\ServiceProvider; use App\Services\PingdomDowntimeNotifier; use App\Services\DigitalOceanServerProvider; class AppServiceProvider extends ServiceProvider{ /** * 设定所有的容器绑定的对应关系 * * @var array */ public $bindings = [ ServerProvider::class => DigitalOceanServerProvider::class, ]; /** * 设定所有的单例模式容器绑定的对应关系 * * @var array */ public $singletons = [ DowntimeNotifier::class => PingdomDowntimeNotifier::class, ]; }
#引導方法
#如果我們要在服務提供者中註冊一個視圖合成器該怎麼做?這就需要用到
boot
方法了。 該方法在所有服務提供者被註冊以後才會被呼叫, 這就是說我們可以在其中訪問框架已註冊的所有其它服務:<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider{ /** * 启动所有的应用服务。 * * @return void */ public function boot() { view()->composer('view', function () { // }); } }
啟動方法的依賴注入
你可以為服務提供者的
boot
方法設定類型提示。服務容器會自動注入你所需要的依賴:use Illuminate\Contracts\Routing\ResponseFactory; public function boot(ResponseFactory $response){ $response->macro('caps', function ($value) { // }); }
#註冊服務提供者
所有服務提供者都是透過設定檔
config/app.php
進行註冊。該檔案包含了一個列出所有服務提供者名字的providers
數組,預設情況下,其中列出了所有核心服務提供者,這些服務提供者啟動Laravel 核心元件,例如郵件、佇列、緩存等等。要註冊提供器,只需要將其新增至陣列:
'providers' => [ // 其他服务提供者 App\Providers\ComposerServiceProvider::class,],
#延遲提供者
如果你的服務提供者只 在服務容器中註冊,可以選擇延遲加載該綁定直到註冊綁定的服務真的需要時再加載,延遲加載這樣的一個提供者將會提升應用的性能,因為它不會在每次請求時都從檔案系統載入。
Laravel 編譯並儲存延遲服務提供者提供的所有服務的列表,以及其服務提供者類別的名稱。因此,只有當你在嘗試解析其中一項服務時,Laravel 才會載入服務提供者。
要延遲載入提供者,需要實作
\Illuminate\Contracts\Support\DeferrableProvider
介面並置一個provides
方法。這個provides
方法傳回該提供者註冊的服務容器綁定:<?php namespace App\Providers; use Riak\Connection; use Illuminate\Support\ServiceProvider; use Illuminate\Contracts\Support\DeferrableProvider; class RiakServiceProvider extends ServiceProvider implements DeferrableProvider{ /** * 注册服务提供者。 * * @return void */ public function register() { $this->app->singleton(Connection::class, function ($app) { return new Connection($app['config']['riak']); }); } /** * 获取由提供者提供的服务。 * * @return array */ public function provides() { return [Connection::class]; } }
本文章首發在 LearnKu.com 網站上。