2012-05-21 60 views
13

我不明白這是如何使用「DI容器」。在官方網站上顯示的例子告訴我什麼:http://pimple.sensiolabs.org瞭解疙瘩

基本上我有一個簡單的網站,它由一組類:數據庫類,緩存類,用戶類和一些更多的處理內容類型。

所有這些類都像Pimple中提到的「服務」,每個服務應該能夠調用另一個服務。現在我正在實例化一個主類中的服務,我使用它作爲一個單例來共享其他類中的服務。

從我讀的內容來看,Pimple完全是這樣的事情,但我該如何使用它? :s

回答

18

有一個教程http://phpmaster.com/dependency-injection-with-pimple/解釋如何使用Pimple作爲DIC。

另一個(但不是必須推薦的)方法是將容器注入到所有需要它的組件中(例如,像ServiceLocator一樣使用它),然後執行文檔中說你應該做的事來獲取對象青春痘:

class SomeClassThatNeedsSession 
{ 
    private $session; 
    public function __construct(Pimple $container) 
    { 
     $this->session = $container['session']; 
    } 
} 

換句話說,你只取你需要什麼,Pimple will handle the lifetime of that object, e.g. whether it needs to be created or is reused。 OffsetGet是ArrayAccess接口的一部分,它允許您像訪問數組一樣訪問對象,因此當您執行$container['foo']時,Pimple將檢查它是否具有爲foo定義的閉包,而不管它是否只是一些參數並相應地組裝服務。

疙瘩是blog post about Lambdas and Closures的結果,您可能想閱讀它以更好地理解它是如何工作的。

+4

將整個容器放入課程是否被認爲是很好的做法?這不是略微違反德米特法則,因爲你給一個班級超過了需要做的工作嗎? – AgmLauncher

+2

@AgmLauncher Demeter法則不適用於根據LoD上的原始文件創建對象的方法。由於服務定位器實際上是創建對象的工廠,因此它並不真正違反LoD。然而,所有使用服務定位器的類將依賴於SL,然後妨礙重用,所以最好不要像使用它一樣,而是按照我給出的第一個鏈接中的建議用法。 – Gordon

+1

如果您在構造函數中注入整個Pimple容器,那麼我們如何才能知道類SomeClassThatNeedsSession的真正依賴關係?我怎麼知道哪些依賴模擬測試? –

4

我不知道疙瘩,但我知道的DI引擎需要實例化。您的對象不會創建其依賴項的實例。相反,DI引擎會根據請求創建它們並進行處理。

因此,如果您的PHP代碼正在創建新實例,我認爲您應該更改它,以便您的代碼獲取DI引擎並從中請求相關性。

+0

Pimple只是一個容器而不是引擎,它不能處理實例化。 – erdeszt

+2

那麼誰爲Pimple實例化?如果無法創建對象,我不會看到這一點。 – duffymo

+1

您可以使用閉包配置Pimple來爲您做實例化。疙瘩將處理對象之間的依賴關係,並實例化每個懶惰,即只在需要時。 – Jason