1. 程式人生 > 程式設計 >Laravel服務容器繫結的幾種方法總結

Laravel服務容器繫結的幾種方法總結

繫結基礎

幾乎所有的服務容器繫結都是在 服務提供者 中完成。

在目錄結構如下圖

Laravel服務容器繫結的幾種方法總結

注:如果一個類沒有基於任何介面那麼就沒有必要將其繫結到容器。容器並不需要被告知如何構建物件,因為它會使用 PHP 的反射服務自動解析出具體的物件。

簡單的繫結

在一個服務提供者中,可以通過 $this->app 變數訪問容器,然後使用 bind 方法註冊一個繫結,該方法需要兩個引數,第一個引數是我們想要註冊的類名或介面名稱,第二個引數是返回類的例項的閉包:

 $this->app->bind('HelpSpot\API',function ($app) {
 return new HelpSpot\API($app->make('HttpClient'));
});

注意到我們將容器本身作為解析器的一個引數,然後我們可以使用該容器來解析我們正在構建的物件的子依賴。

繫結一個單例

singleton 方法繫結一個只會解析一次的類或介面到容器,然後接下來對容器的呼叫將會返回同一個物件例項:

$this->app->singleton('HelpSpot\API',function ($app) {
 return new HelpSpot\API($app->make('HttpClient'));
});

繫結原始值

你可能有一個接收注入類的類,同時需要注入一個原生的數值比如整型,可以結合上下文輕鬆注入這個類需要的任何值:

$this->app->when('App\Http\Controllers\UserController')
 ->needs('$variableName')
 ->give($value);

繫結介面到實現

服務容器的一個非常強大的功能是其繫結介面到實現。我們假設有一個 EventPusher 介面及其實現類 RedisEventPusher ,編寫完該介面的 RedisEventPusher 實現後,就可以將其註冊到服務容器:

$this->app->bind(
 'App\Contracts\EventPusher','App\Services\RedisEventPusher'
);

這段程式碼告訴容器當一個類需要 EventPusher 的實現時將會注入 RedisEventPusher,現在我們可以在構造器或者任何其它通過服務容器注入依賴的地方進行 EventPusher 介面的依賴注入:

use App\Contracts\EventPusher;

/**
 * 建立一個新的類例項
 *
 * @param EventPusher $pusher
 * @return void
 */
public function __construct(EventPusher $pusher){
 $this->pusher = $pusher;
}

上下文繫結

有時侯我們可能有兩個類使用同一個介面,但我們希望在每個類中注入不同實現,例如,兩個控制器依賴 Illuminate\Contracts\Filesystem\Filesystem 契約的不同實現。Laravel 為此定義了簡單、平滑的介面:

use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\VideoController;
use App\Http\Controllers\PhotoControllers;
use Illuminate\Contracts\Filesystem\Filesystem;

$this->app->when(PhotoController::class)
 ->needs(Filesystem::class)
 ->give(function () {
 return Storage::disk('local');
 });

$this->app->when(VideoController::class)
 ->needs(Filesystem::class)
 ->give(function () {
 return Storage::disk('s3');
 });

標籤

少數情況下,我們需要解析特定分類下的所有繫結,例如,你正在構建一個接收多個不同 Report 介面實現的報告聚合器,在註冊完 Report 實現之後,可以通過 tag 方法給它們分配一個標籤:

$this->app->bind('SpeedReport',function () {
 //
});

$this->app->bind('MemoryReport',function () {
 //
});

$this->app->tag(['SpeedReport','MemoryReport'],'reports');

這些服務被打上標籤後,可以通過 tagged 方法來輕鬆解析它們:

$this->app->bind('ReportAggregator',function ($app) {
 return new ReportAggregator($app->tagged('reports'));
});

擴充套件繫結

extend 方法允許對解析服務進行修改。例如,當服務被解析後,可以執行額外程式碼裝飾或配置該服務。extend 方法接收一個閉包來返回修改後的服務:

$this->app->extend(Service::class,function($service) {
 return new DecoratedService($service);
});

總結

到此這篇關於Laravel服務容器繫結的文章就介紹到這了,更多相關Laravel服務容器繫結內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!