什麼是Service Container
The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection.
從Laravel官方文件對於Service Container的解釋可以看出,它的作用就是幫助我們管理和進行依賴注入的。
為什麼要用Service Container
在《依賴注入》中,我們看到使用依賴注入可以極大的降低程式碼的耦合度,但是也帶來了一個缺點,就是需要自己管理注入的對象。
如果一個元件有很多依賴,我們需要創建多個參數的setter方法來傳遞依賴關係,或者建立一個多個參數的建構函數來傳遞它們,另外在使用元件前還要每次都創建依賴,這讓我們的程式碼像這樣不易維護。
所以為依賴實例提供一個容器(Service Container),就是一個實用且優雅的方法。
例如下面是laravel的入口檔案(已去掉註解):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
首先看bootstrap/app.php
,其中$app
是 Illuminate\Foundation\Application
的一個實例,而Illuminate\Foundation\Application
類別繼承自Container,所以$app
其實就是一個Service Container。
然後下面的三個singleton方法定義了當依賴Illuminate\Contracts\Http\Kernel
、Illuminate\Contracts\Console\Kernel
、Illuminate\Contracts\Debug \ExceptionHandler
這三個介面時,注入哪個類別的單例。
然後看public/index.php
,其中的make方法其實就是用Service Container來new一個Illuminate\Contracts\Http\Kernel
實例,跟普通new的差別就是會把他的依賴自動注入進去。
是不是很簡潔?
其實不單是Laravel,像是Yii2、Phalcon等框架都透過實作容器來管理依賴注入。
如何使用Service Container
既然是一個容器,無非就是兩個事,往裡面放東西和往外取東西,對應到Service Container就是綁定(Binding)和解析(Resolving )。
取得容器
在Laravel的Service Provider中,可以透過$this->app
取得容器,除此之外,還可以使用app ()
來取得容器。
如果在Laravel外使用Service Container,直接new一個Illuminate\Container\Container
就可以獲得容器了。
以下都用$container代表取得到的容器。
綁定
綁定傳回介面的實例
1 2 3 4 5 6 |
|
- ##綁定單例
singletion 方法綁定一個只會被解析一次的類別或介面到容器中,且後面的呼叫都會從容器中傳回相同的實例:
1
2
3
$container
->singleton(
'BarInterface'
,
function
(){
return
new
Bar();
});
登入後複製
- 綁定實例
你也可以使用instance 方法,將一個已經存在的物件實例綁定到容器中。後面的呼叫都會從容器中回傳指定的實例:
1
2
3
4
$bar
=
new
Bar();
$bar
->setSomething(
new
Something);
$container
->instance(
'Bar'
,
$bar
);
登入後複製
- 情境綁定
有時候,你可能有兩個類別使用到相同接口,但你希望每個類別都能注入不同實作。
1
2
3
4
5
6
$container
->when(
'Man'
)
->needs(
'PartnerInterface'
)
->give(
'Woman'
);
$container
->when(
'Woman'
)
->needs(
'PartnerInterface'
)
->give(
'Man'
);
登入後複製
- 標記
#有些時候,可能需要解析某個「分類」下的所有綁定。解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$container
->bind(
'Father'
,
function
() {
//
});
$container
->bind(
'Mother'
,
function
() {
//
});
$container
->bind(
'Daughter'
,
function
() {
//
});
$container
->bind(
'Son'
,
function
() {
//
});
$container
->tag([
'Father'
,
'Mother'
,
'Daughter'
,
'Son'
],
'familyMembers'
);
$container
->bind(
'Family'
,
function
(
$container
) {
return
new
Family(
$container
->tagged(
'familyMembers'
));
});
登入後複製
- make方法 #
1 |
|
- 陣列方法
1 |
|
解析被標記綁定
1 2 3 4 5 |
|
解析事件
每當服務容器解析一個物件時就會觸發事件。你可以使用 resolving 方法監聽這個事件。
1 2 3 4 5 6 7 |
|
相關推薦:最新的五個Laravel影片教學