2013-02-14 47 views
8

我想在我的实体类上使用服务管理器,但我不知道这样做的最佳方法。因为我们可以通过以下方式调用服务管理器:$ this-> getServiceLocator();我们可以使用$ this-> getServiceLocator();在模型类中使用ServiceManager的最佳方法?

但是,在我的实体类,即使我实现ServiceLocatorAwareInterface我可以retieve的ServiceManager,因为我的实体类未与服务经理称:

那么,什么是最好的办法:

1 - 通过我的控制器在我的实体类中传递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为你建立你的模型,并将你需要的任何东西直接注入到模型中。

服务配置:

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

将任何服务管理器里面配置你的依赖,然后用它来注入任何依赖到你的模型,服务等为您服务。

,如果你想使用工厂方法,而不是封闭的例子工厂类:

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

范例模型,你试图通过服务管理器实例。

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 /服务定位到你的模型,但随后你的模型将依赖于服务定位。

+2

非常有用的答案! 另一个不将ServiceManager注入模型的原因是通过这种方式,我们不能序列化我们的对象(因为ServiceManager上的闭包)。所以我们无法保存会话中的模型。 – 2013-02-14 15:53:55

+1

我觉得唯一需要补充的是你不应该过度使用'Closure's。改写工厂类。这将提升整体性能,因为这些类只会根据需求进行实例化。所有闭包都将在每个请求中实例化。 – Sam 2013-02-14 18:02:06

+1

还有一件事:如果某些依赖项是绝对**需要**这是强烈建议使用'__construct()'或注入,而不是安装程序注入 – Sam 2013-02-14 18:03:49

相关问题