2013-11-28 33 views
5

我剛開始使用ZF2,我非常享受它。Zend Registry for ZF2的替代品

讓我困惑的一件事是沒有註冊表組件。我意識到服務管理器在大多數情況下會使註冊表過時。我很依賴它,它很棒。

但有時我發現自己需要訪問'全局'對象,而且我無法訪問服務管理器。例如,在我的Domain \ User對象中,我需要訪問Zend \ Log。

我不想讓服務管理器在我的域對象中可用,因爲它們很漂亮,質樸,並且不受這些考慮因素的影響。無論何時需要,我都可以「新建」一個日誌實例,但我經常這樣做,我寧願預先配置一個實例。我可以用單身包裝它,但這似乎是一個落後的步驟。我可以創建自己的迷你註冊表,但如果這是一個好主意,我肯定Zend的人會留下這樣一個組件。

那麼,還有什麼其他的選擇?

編輯:

那麼,我可以使用Zend DI嗎?我看到這個問題部分覆蓋它,Configuring class alias for using with Zend\Di\Di

+4

「正確的」方法是將Log對象作爲依賴項傳遞到Domain \ User對象中。日誌記錄不是你通常在域模型中做的事情 - 但是你能解釋一些關於你爲什麼需要這個的東西嗎? –

+0

你好,我使用它只是爲了得到一個變量的var_dump或print_r。只是爲了調試,真的。 –

+0

您的編輯聽起來不錯 - Zend \ Di \ Di似乎是在對象構建中引發依賴關係的不錯選擇。但是,正如你所提到的,只有在它根本不是真正的依賴關係時才應該這樣做(例如日誌記錄)。 – P0rnflake

回答

3

你正在解決依賴注入的問題。之前我已經寫過關於此主題的博客,如何refactor towards dependency injection以及如果您有像登錄器那樣的soft dependencies該怎麼辦。

這個想法是你注入預先配置的記錄器。當您的Domain \ User對象被創建時,記錄器被注入。這使Domain \ User對象只依賴於記錄器,而不知道如何創建記錄器。如果您依賴Logger界面,則會更好,因此您可以交換到任何您想要的記錄器實現。

作爲一個例子,我想你正在使用Zend \日誌。你有一個類似Zend\Log\Logger的記錄器,附有各種作者。記錄器執行Zend\Log\LoggerInterface

你的域\用戶等級:

namespace Domain; 

Zend\Log\LoggerInterface; 

class User 
{ 
    protected $logger; 

    public function __construct(LoggerInterface $logger) 
    { 
     $this->logger = $logger; 
    } 

    public function doSomething() 
    { 
     $this->logger->info('Do Something'); 

     // 
    } 
} 

對於Zend框架,你應該與工廠工作到這個記錄器注入到你的對象。最好的方法是首先將Logger定義爲服務,因爲您也可以將記錄器重用爲其他對象。

注意我在這裏使用Service Manager而不是Zend \ Di。 Zend \ Di已經過時,並由更快和更靈活的Zend \ ServiceManager取代。兩者都可以實現依賴注入。

廠家爲您記錄:

namespace MyModule\Factory; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

use Zend\Log\Logger; 

class LoggerFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $logger = new Logger; 
     // do more with $logger here 

     return $logger; 
    } 
} 

然後註冊這個工廠來創建服務「記錄儀」爲您服務。在您的module.config.php中:

'service_manager' => array(
    'factories' => array(
     'logger' => 'MyModule\Factory\LoggerFactory', 
    ), 
), 

現在logger可在您的服務管理器中使用。對於您的域模型,請執行相同的操作。首先創建一個工廠:

namespace MyModule\Factory; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

use Domain\User; 

class UserFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $logger = $serviceLocator->get('logger'); 

     $user = new User($logger); 
     return $user; 
    } 
} 

然後註冊這一個了:

'service_manager' => array(
    'factories' => array(
     'logger' => 'MyModule\Factory\LoggerFactory', 
     'Domain\User' => 'MyModule\Factory\UserFactory', 
    ), 
), 

如果你有機會獲得服務定位器,你可以得到域\用戶和記錄器自動注入:

$user = $sl->get('Domain\User');