2013-02-14 4 views
8

Я пытаюсь использовать Service Manager в классе сущности, но я не знаю, как это сделать.Лучший способ использования ServiceManager в классе модели?

Это легко на контроллере, потому что мы можем позвонить менеджеру сервиса с помощью: $ this-> getServiceLocator();

Но, в моем классе сущности, даже если я реализую ServiceLocatorAwareInterface я могу retieve ServiceManager, потому что мой класс сущности не звонить с менеджером службы:

Так что это лучший способ:

1 - Pass serviceManager в моем классе сущности из моего контроллера 2 - Использование ServiceManager для создания класса объектов 3 - ...?

Чтобы лучше понять мою проблему, что мой код, который не работает:

Мой объект класса:

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; 
} 

ответ

18

Я бы не вводить ServiceManager в модель (хотя можно). Я бы предпочел получить ServiceManager для создания вашей модели для вас и ввести все, что вам нужно непосредственно в модель.

Service 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', 

Размещать любую из ваших зависимостей внутри Service Manager Config, а затем использовать это, чтобы внедрить какие-либо зависимости в вашей модели, услуги и т.д. для вас.

Пример завод класс, если вы хотите использовать фабричный метод, а не закрытия:

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; 
    } 
} 

Пример модели вы пытаетесь создать экземпляр с помощью 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. 
} 

в контроллере:

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

Вы можете вводить SergiceManager/в ваши поиска сервиса моделей, но тогда ваши модели будут зависеть от ServiceLocator.

+2

Очень полезный ответ! Еще одна причина не вводить ServiceManager в модель таким образом, что мы не можем сериализовать наш объект (из-за закрытия в ServiceManager). И поэтому мы не можем сохранять модели на сеансе. –

+1

Единственное, что нужно добавить, я чувствую, что вы не должны чрезмерно использовать 'Closure' слишком много. Вместо этого напишите заводские классы. Это повысит общую производительность, поскольку классы будут создаваться только по требованию. Все Closures будут создаваться при каждом отдельном запросе. – Sam

+1

Еще одна вещь: если некоторые зависимости абсолютно необходимы **, настоятельно рекомендуется использовать '__construct()' или инъекцию вместо Setter-Injection – Sam

Смежные вопросы