假设:Event\Service\EventService
是我的个人对象,适用于Event\Entity\Event
个实体
此代码适用于ActionController:
$eventService = $this->getServiceLocator()->get('Event\Service\EventService');
如何以同样的方式在$eventService
中获得Zend\Form\Form
?
答案 0 :(得分:5)
如果你有这样的依赖,你有两个选择。在您的情况下,Form
取决于Service
。第一个选项是注入依赖项:
class Form
{
protected $service;
public function setService(Service $service)
{
$this->service = $service;
}
}
$form = new Form;
$form->setService($service);
在这种情况下,$form
不知道$service
的位置,并且通常被认为是一个好主意。为了确保每次需要Form
时不需要自己设置所有依赖项,可以使用服务管理器创建工厂。
创建工厂的一种方法(还有更多)是向模块类添加getServiceConfiguration()
方法,并使用闭包来实例化Form
对象。这是将Service
注入Form
:
public function getServiceConfiguration()
{
return array(
'factories' => array(
'Event\Form\Event' => function ($sm) {
$service = $sm->get('Event\Service\EventService');
$form = new Form;
$form->setService($service);
return $form;
}
)
);
}
然后,您只需从服务经理处获取Form
即可。例如,在您的控制器中:
$form = $this->getServiceLocator()->get('Event\Form\Event');
第二个选项是拉依赖关系。虽然不建议像表单这样的类,但您可以注入服务管理器,以便表单可以自行提取依赖项:
class Form
{
protected $sm;
public function setServiceManager(ServiceManager $sm)
{
$this->sm = $sm;
}
/**
* This returns the Service you depend on
*
* @return Service
*/
public function getService ()
{
return $this->sm->get('Event\Service\EventService');
}
}
然而,第二个选项将您的代码与不必要的耦合耦合在一起,这使得测试代码非常困难。所以请使用依赖注入,而不是自己拉依赖。只有极少数情况下您可能想要自己提取依赖项:)
答案 1 :(得分:3)
您可以使用module.php中的所有选项配置表单。在以下代码中我:
代码:
public function getServiceConfiguration()
{
return array(
'factories' => array(
'my_form' => function ($sm) {
$model = new \MyModule\Form\MyForm($sm->get('something1'));
$obj = $sm->get('something2');
$model->setSomething($obj);
return $model;
},
),
);
}
然后在控制器中,以下行将使用所有必需的依赖项填充您的对象
$form = $this->getServiceLocator()->get('my_form');
答案 2 :(得分:0)
使用表单元素管理器获取控制器中的表单:
$form = $this->getServiceLocator()->get('FormElementManager')->get('Path\To\Your\Form', $args);
然后在你的表格中将成为这个
<?php
namespace Your\Namespace;
use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ ServiceLocatorAwareTrait;
class MyForm extends Form implements ServiceLocatorAwareInterface {
use ServiceLocatorAwareTrait;
public function __construct($class_name, $args)
{
/// you cannot get the service locator in construct.
}
public function init()
{
$this->getServiceLocator()->get('Path\To\Your\Service');
}
}