2013-10-30 17 views
2

所以這可能是一個相當簡單的問題,但我似乎無法找到一個非常直接的答案。我應該可以繼續閱讀源代碼,直到我明白爲止,但我希望能夠理解這樣做的過程。laravels IoC/Dependency Injector如何對靜態實例進行intsantiate?

我明白IoC和依賴注入,我當然不是很有經驗,但我很好理解他們正在努力完成什麼。那麼這個Laravel如何實例化爲靜態實例呢?我知道它使用PHP的反射,但我仍然從非靜態方法轉向靜態方法。另外我知道Laravel不是實現這種設計的唯一框架,但它是我的首選和最理解的框架。

+1

好問題!我也不太瞭解它,但它似乎與命名空間有關。 –

回答

4

當您在門面上調用靜態方法時,它正在由Facade類中的魔術__callStatic方法處理。此方法獲取服務於Facade的基礎類並代理靜態調用。

讓我們看一個例子門面:

<?php 
class MyFacade extends Facade { 
    public function getFacadeAccessor() { return "MyFacade"; } 
} 

有了這個例子,當我們做對類的調用以靜態方式,例如:MyFacade::doSomething()沒有靜態方法的類存在。然而,底層的Facade基類包含一個將被調用的方法__callStatic

Facade Class Source Code

public static function __callStatic($method, $args) 
{ 
     $instance = static::resolveFacadeInstance(static::getFacadeAccessor()); 

     switch (count($args)) 
     { 
       case 0: 
         return $instance->$method(); 
     // Snipped for brevity... 

然後,這個方法查找底層類服務門面。如果Facade上的​​方法返回一個字符串,則使用應用程序的IOC容器中的匹配項(即$app['MyFacade'])。如果我們從​​方法返回一個對象,它將被用來代替(即public function getFacadeAccessor(){ return new MyClass(); }

+1

非常感謝這一點,我試圖弄清楚通過源代碼發生了什麼,但一直在努力尋找實例化的部分。我也不知道魔法__callStaic方法。酷,我可以等待嘗試在我的依賴注入器中實現這一點! – SamSquanch

0

原來,Laravel實例化引擎蓋下的類!在this網站上,這個傢伙讓你更加了解Laravel的核心,用它來創建一個新的外觀。順便說一下,他解釋了山雀是如何工作的!

它很簡單,actualy:
1 - 創建從Laravel的Facade類擴展與像一個單一的呼叫CLASSE:

<?php namespace Name\Space; 

use Illuminate\Support\Facades\Facade; 

class MyClass extends Facade { 

    /** 
    * Get the registered name of the component. 
    * 
    * @return string 
    */ 
    protected static function getFacadeAccessor() { return 'myclass'; } 

} 

...這讓Laravel尋找$app['myclass']。因此,ServiceProvider將綁定myclassMyClass(根據Laravel的約定)。

2 - 對此,當然,您必須創建一個服務提供商。 服務提供商將負責返回namespace,在這種情況下爲Name\Space,您可能希望將'變成外牆'。

3 - 您必須在app/config/app.phpproviders陣列中註冊您的服務提供商。

現在,如果你注意更多,你會意識到Laravel所做的只是導入一個命名空間,並將它理解爲一個類,同樣也是。在引擎蓋下,它會調用一個實例,但對於用戶(程序員)來說,它看起來像一個靜態調用。

我希望我已經清楚了!看看我給你的鏈接,並且玩得開心! :D

+1

這是一個固體答案,但並不完全是我想弄清楚的,我想知道的是Facade和IoC實際上是如何處理非靜態類到靜態實例的 – SamSquanch

+1

服務提供者創建一個IoC綁定在上面的例子中,後來,MyClass外觀將使用IoC容器將「myclass」解析爲與之綁定的任何東西,然後,Facade使用PHP魔術方法在Facade上採用任何靜態調用的方法並在已解析的對象上運行它(「myclass」又稱爲「MyClass」的一個實例)[你可以在這裏看到這個動作](https:/ /github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Facade.php#L196)。 – fideloper

+0

很好解釋,@fideloper!你能否改進答案來涵蓋你描述的最後一部分? –