2013-02-14 31 views
8

Tôi đang cố gắng sử dụng Trình quản lý Dịch vụ trên lớp tổ chức của mình nhưng tôi không biết cách tốt nhất để làm điều đó.Cách tốt nhất để sử dụng ServiceManager trong Lớp Mô hình là gì?

Thật dễ dàng trên bộ điều khiển vì chúng tôi có thể gọi cho người quản lý dịch vụ bằng: $ this-> getServiceLocator();

Nhưng, trong lớp thực thể của tôi, ngay cả khi tôi thực hiện ServiceLocatorAwareInterface tôi có thể retieve ServiceManager vì lớp thực thể của tôi không được gọi với người quản lý dịch vụ:

Vì vậy, cách tốt nhất là gì:

1 - Vượt qua serviceManager trong lớp thực thể của tôi từ bộ điều khiển của tôi 2 - Sử dụng ServiceManager để xây dựng lớp thực thể của tôi 3 - ...?

Để hiểu tốt nhất vấn đề của tôi, đó là mã của tôi mà không làm việc:

My tổ chức lớp:

class Demande extends ArraySerializable implements InputFilterAwareInterface { 
/../ 
    public function getUserTable() { 
    if (! $this->userTable) { 

     $sm = $this->getServiceLocator();//<== doesn't work ! 
     $this->userTable = $sm->get ('Application\Model\UserTable'); 
    } 
    return $this->userTable; 
} 

Trả lời

18

tôi sẽ không tiêm ServiceManager vào mô hình của bạn (mặc dù bạn có thể). Thay vào đó, tôi muốn ServiceManager xây dựng Mô hình của bạn cho bạn và tiêm bất cứ thứ gì bạn cần trực tiếp vào mô hình.

Dịch vụ Config:

'factories' => array(
    'SomethingHere' => function($sm) { 
     $model= new \My\Model\Something(); 

     return $model; 
    }, 
    '\My\Model\Demande' => function($sm) { 
     $model= new \My\Model\Demande(); 
     /** 
     * Here you use the SM to inject any dependencies you need 
     * into your model/service what ever.. 
     */ 
     $model->setSomething($sm->get('SomethingHere')); 

     return $model; 
    }, 
    /** 
    * Alternatively you can provide a class implementing 
    * Zend\ServiceManager\FactoryInterface 
    * which will provide an instance for you instad of using closures 
    */ 
    '\My\Model\DemandeDefault' => '\My\Model\DemandeFactory', 

Nơi nào phụ thuộc của bạn bên trong Service Manager Config, và sau đó sử dụng để tiêm bất kỳ phụ thuộc vào mô hình của bạn, dịch vụ vv cho bạn.

Một nhà máy ví dụ lớp nếu bạn muốn sử dụng phương pháp nhà máy chứ không phải là đóng cửa:

DemandeFactory.php

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

class DemandeFactory implements FactoryInterface 
{ 
    /** 
    * Create a new Instance 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * @return Demande 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $config = $serviceLocator->get('Config'); // if you need the config.. 
     // inject dependencies via contrustor 
     $model = new \My\Model\Demande($serviceLocator->get('SomethingHere')); 
     // or using setter if you wish. 
     //$model->setSomething($serviceLocator->get('SomethingHere')); 

     return $model; 
    } 
} 

Một ví dụ mẫu bạn đang cố gắng để nhanh chóng thông qua Service Manager.

Demande.php

class Demande 
{ 
    protected $_something; 

    /** 
    * You can optionally inject your dependancies via your constructor 
    */ 
    public function __construct($something) 
    { 
     $this->setSomething($something); 
    } 

    /** 
    * Inject your dependencies via Setters 
    */ 
    public function setSomething($something) 
    { 
     $this->_something = $something; 
    } 

    // Something will be injected for you by the Service Manager 
    // so there's no need to inject the SM itself. 
} 

Trong điều khiển của bạn:

public function getDemande() 
{ 
    if (! $this->_demande) { 
     $sm = $this->getServiceLocator(); 
     $this->_demande = $sm->get ('\My\Model\Demande'); 
    } 
    return $this->_demande; 
} 

Bạn có thể tiêm các SergiceManager/ServiceLocator vào các mô hình của bạn, nhưng sau đó mô hình của bạn sẽ phụ thuộc vào ServiceLocator.

+2

Câu trả lời rất hữu ích! Một lý do khác để không tiêm ServiceManager vào mô hình là bằng cách này, chúng tôi không thể tuần tự hóa đối tượng của chúng tôi (vì đóng cửa trên ServiceManager). Và vì vậy chúng tôi không thể lưu mô hình trên phiên. –

+1

Điều duy nhất cần được thêm vào tôi cảm thấy là bạn không nên sử dụng quá nhiều 'Closure' quá nhiều. Thay vào đó, hãy viết các lớp nhà máy. Điều này sẽ thúc đẩy hiệu suất tổng thể, vì các lớp học sẽ chỉ được khởi tạo theo yêu cầu. Tất cả các đóng cửa sẽ được khởi tạo trên mỗi yêu cầu duy nhất. – Sam

+1

Một điều nữa: Nếu một số phụ thuộc là hoàn toàn ** bắt buộc ** được khuyến khích sử dụng '__construct()' hoặc tiêm thay vì Setter-Injection – Sam

Các vấn đề liên quan