2013-07-26 22 views
7

Tôi đang gặp khó khăn trong việc tìm ra cách để có được cá thể ServiceManager từ bên trong lớp tùy chỉnh.ZF2: làm thế nào để tôi nhận được phiên bản ServiceManager từ bên trong lớp tùy chỉnh

Bên trong bộ điều khiển rất dễ dàng:

$this->getServiceLocator()->get('My\CustomLogger')->log(5, 'my message'); 

Bây giờ, tôi đã tạo ra một vài lớp học độc lập và tôi cần phải lấy Zend\Log dụ bên trong lớp đó. Trong v.1 Zend Framework tôi đã làm nó thông qua cuộc gọi tĩnh:

Zend_Registry::get('myCustomLogger'); 

Làm thế nào tôi có thể lấy lại My\CustomLogger trong ZF2?

+4

Ngoài câu trả lời của Jerry, tôi khuyên bạn chỉ nên tiêm phụ thuộc bạn cần vào lớp tùy chỉnh. Vì vậy, nếu bạn chỉ cần đối tượng logger trong lớp tùy chỉnh của bạn thì làm cho nhà máy của lớp tùy chỉnh của bạn tiêm cá thể logger khi tạo một cá thể mới của lớp tùy chỉnh của bạn. – Ruben

+0

Như Sam và Ruben đã chỉ ra, sẽ tốt hơn nếu KHÔNG có lớp của bạn phụ thuộc vào ServiceManager. Thay vào đó, nó sẽ là tốt hơn để tiêm logger vào lớp trực tiếp. Bạn có thể thực hiện điều này thông qua một Trình khởi tạo tìm kiếm một "LoggerAwareInterface" tùy chỉnh HOẶC tạo một lớp nhà máy cho lớp tùy chỉnh của bạn. –

Trả lời

11

Làm cho lớp tùy chỉnh của bạn triển khai ServiceLocatorAwareInterface.

Khi bạn khởi tạo nó với ServiceManager, nó sẽ thấy giao diện đang được triển khai và tự tiêm vào lớp.

Lớp học của bạn giờ đây sẽ có người quản lý dịch vụ hoạt động trong suốt quá trình hoạt động.

<?php 
namespace My; 

use Zend\ServiceManager\ServiceLocatorAwareInterface; 
use Zend\ServiceManager\ServiceLocatorAwareTrait; 

class MyClass implements ServiceLocatorAwareInterface{ 
    use ServiceLocatorAwareTrait; 


    public function doSomething(){ 
     $sl = $this->getServiceLocator(); 
     $logger = $sl->get('My\CusomLogger') 
    } 
} 

// later somewhere else 
$mine = $serviceManager->get('My\MyClass'); 

//$mine now has the serviceManager with in. 

Tại sao tính năng này hoạt động?

Điều này chỉ hoạt động trong ngữ cảnh của Zend \ Mvc, mà tôi cho rằng bạn đang sử dụng vì bạn đã đề cập đến bộ điều khiển.

Nó hoạt động vì Zend\Mvc\Service\ServiceManagerConfig thêm bộ khởi tạo vào ServiceManager.

$serviceManager->addInitializer(function ($instance) use ($serviceManager) { 
    if ($instance instanceof ServiceLocatorAwareInterface) { 
     $instance->setServiceLocator($serviceManager); 
    } 
}); 

Hãy thử và cho tôi biết điều gì sẽ xảy ra.

+7

Cách tiếp cận chung là chính xác, tuy nhiên tôi muốn gợi ý rằng bạn không nên có ServiceLocator như một phụ thuộc, nhưng chỉ những thứ bạn cần từ serviceManager (tức là lớp ghi nhật ký hoặc bộ chuyển đổi db hoặc không có) – Sam

+0

Cảm ơn Jerry. Nó đã làm việc. – user2033934