從根本上說,依賴注入不是讓物件創建一個依賴關系,也不是讓工廠物件去創建物件,而是將所需的依賴變成一個外部物件,使之成為一個"某些人的問題”
你為"某些人的問題”注入了類的依賴關系,在Laravel中,這個"某人”是 服務容器 ,在Laravel中,服務容器負責通過建構式注入類的依賴關系,
任何時候,你在一個控制器類中請求一個依賴,這個服務容器負責:
- 自動地在建構式中檢測依賴關系
- 如果需要構建這個依賴關系
- 通過建構式創建物件形成依賴關系
來看一個非常簡單的例子,
1 <?php 2 namespace App\Http\Controllers; 3 use App\User; 4 use App\Repositories\UserRepository; 5 use App\Http\Controllers\Controller; 6 class UserController extends Controller 7 { 8 protected $userRepository; 9 public function __construct(UserRepository $userRepository) 10 { 11 $this->userRepository = $userRepository; 12 } 13 public function show($id) 14 { 15 $user = $this->userRepository->find($id); 16 return view('user.profile', ['user' => $user]); 17 } 18 }
假如,你有一個 UserController 類需要 UserRepository 作為一個建構式依賴,
- 服務容器使用
PHP的 反射類 來檢測,事實UserRepository需要被優先決議, - 然后,它構造
UserRepository實體, - 然后,它構造
UserController類實體,
依賴關系是如何被決議和注入的,我被很多 Laravel 開發人員不知道這個簡單而強大的技術感到迷惑, 這是一個非常強大的技術,它可以被用來解決復雜物件的依賴關系,
如果由于某種原因,您不希望Laravel自動構建一個物件,您還可以通過傳遞一個可用于創建依賴關系的回呼來告訴Laravel Service Container如何構造該物件,
1 <?php 2 $container->bind('My\Service', function($container) { 3 return new My\Service($container->make('My\AnotherService')); 4 });
您需要創建一個服務提供商來注冊上述服務,
1 <?php 2 namespace App\Providers; 3 use Illuminate\Support\ServiceProvider; 4 class MyServiceProvider extends ServiceProvider 5 { 6 public function register() 7 { 8 $this->app->singleton(\My\Service::class, function ($app) { 9 return new \My\Service($app->make('My\AnotherService')); 10 }); 11 } 12 }
當 My\Service 需要被決議的時候,負責回傳一個物件的回呼函式就會被呼叫,
1 <?php 2 namespace App\Http\Controllers; 3 use App\User; 4 use App\Http\Controllers\Controller; 5 class MyController extends Controller 6 { 7 protected $myService; 8 public function __construct(\My\Service $myService) 9 { 10 $this->myService = $myService; 11 } 12 // .. 方法 13 }
真實的例子
假設你的應用需要Facebook的PHP SDK來訪問Facebook的API,你的控制器就是這樣的:
1 <?php 2 namespace App\Http\Controllers; 3 use App\User; 4 use App\Http\Controllers\Controller; 5 use Facebook\Facebook; 6 class FacebookApiAccessController extends Controller 7 { 8 protected $facebook; 9 public function __construct(Facebook\Facebook $facebook) 10 { 11 $this->facebook = $facebook; 12 } 13 //.. action methods here 14 }
現在,您需要告訴Service Container如何構建 Facebook\Facebook的實體.
1 <?php 2 $container->singleton('Facebook\Facebook', function() { 3 return new \Facebook\Facebook([ 4 'app_id' => config('services.facebook.app_id'), 5 'app_secret' => config('services.facebook.app_secret'), 6 'default_graph_version' => 'v2.10', 7 ]); 8 });
注意,我已經呼叫了方法singleton而不是bind, 唯一的區別是用singleton注冊的服務被快取,隨后的決議服務呼叫回傳快取的服務,
結論
依賴注入是一種強大的技術,你可以在 Laravel 中用來簡化物件的創建. 默認情況下, Laravel 的服務容器會自動的用反射去檢測和解決依賴關系. 但是, 你可以指定回呼來決議服務.
phper在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那里入手去提升,對此我整理了一些資料,包括但不限于:分布式架構、高可擴展、高性能、高并發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨需要的可以免費分享給大家,需要的(點擊→)我的官方群677079770
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/122674.html
標籤:PHP
