laravel 自定義服務提供者

導語

laravel 的服務提供者,是框架的核心,提供了路由、日誌、緩存等功能。這裏要實現的需求是使用第三方 API 獲取天氣狀況,涉及到服務提供者、契約、依賴注入等方面。相關內容能夠經過下方參考資料進行了解,本文內容不進行展開介紹,代碼可查看 GitHubphp

建立服務提供者

  1. 可使用 artisan 快捷的建立服務提供者,執行 php artisan make:provider WeatherServiceProvider 即在 app/Providers 目錄下建立了 WeatherServiceProvider.php 文件;
  2. config/app.php 中註冊服務提供者,在 providers 數組中將建立的服務提供者 App\Providers\WeatherServiceProvider::class, 寫入,以下

註冊服務提供者

建立契約

  1. app 目錄下新建 Contracts 目錄用以存放契約文件;
  2. app/Contracts 目錄下建立契約,即 Weather.php 接口文件。在接口中只定義了 public function getWeather($cityName); 一個方法用於獲取天氣信息;

實現契約

  1. app 目錄下新建 Service/Weather 目錄用於存放實現 Weather.php 契約的文件;
  2. 選擇一個第三方的天氣 API 來實現契約。這裏使用的是心知天氣。關於 API 的調用,能夠查看文檔
  3. 最終建立的文件是 app/Service/Weather/Xinzhi.php。繼承了 Weather.php 接口文件,全部要實現 getWeather 方法,代碼可查看 GitHub
  4. 這裏先埋個伏筆。除了上面的 Xinzhi.php,另外選擇和風天氣實現契約,文件爲 app/Service/Weather/Hefeng.php。代碼查看 GitHub

服務提供者綁定

咱們已經實現了契約,接下來就是綁定具體實現類。回到開始建立的服務提供者,在 register 方法中添加以下代碼html

$this->app->bind('App\Contracts\Weather', function() {
    return new Xinzhi();
});

最後就能夠正常使用了。新建路由,而後測試。試下經過依賴注入調用laravel

public function getWeather(Request $request, Weather $weather)
{
    return $weather->getWeather($request->input('city', 'beijing'));
}

沒有問題git

測試

解耦

完成上述全部步驟,這個需求已經實現了。看起來很麻煩是吧,徹底能夠封裝一個函數,直接調用就能夠了,沒有必要自定義服務提供者、建立契約。實際上述步驟,其中的一個目的就是小標題那兩個字——解耦
假設一下,咱們須要在不少代碼中使用這個功能,忽然有一天,這個 API 掛了,怎麼辦?四處去查找、檢查代碼,而後再去修改,同時要注意參數、返回值等。光是聽起來就很煩了。這個時候,若是咱們的代碼按照上述的步驟進行開發,解決方法就大不相同了。簡而言之,一行代碼就能夠搞定。
還記得上面那個伏筆吧,一共有兩個實例實現了接口。將自定義的服務提供者 register 作以下修改github

$this->app->bind('App\Contracts\Weather', function() {
       // return new Xinzhi();
        return new Hefeng();
});

修改了契約的綁定,全部使用 Weather 契約進行依賴注入的實例,都會由 Xinzhi.php 實例切換到 Hefeng.php 實例。數組

契約固然不止解耦這一個做用,代碼更容易理解、更方便維護,甚至能夠當作簡明的開發文檔。更多的深刻理解,請查看下方參考資料。緩存


參考資料:底層原理 —— 服務提供者底層原理 —— 契約(Contracts)Laravel 服務容器實例教程 —— 深刻理解控制反轉(IoC)和依賴注入(DI) Laravel 從學徒到工匠系列 依賴注入篇app

相關文章
相關標籤/搜索