Zend framework2 在ZF2的字段集中获取objectManager/serviceLocator

Zend framework2 在ZF2的字段集中获取objectManager/serviceLocator,zend-framework2,service-locator,Zend Framework2,Service Locator,为了在fieldset的init()函数中获得对象管理器,我遵循 起初我发现我必须改变 public function setServiceLocator(ServiceLocator $sl) 到 否则我会出错: setServiceLocator() must be compatible with that of Zend\ServiceManager\ServiceLocatorAwareInterface::setServiceLocator() 调用$this->getServic

为了在fieldset的init()函数中获得对象管理器,我遵循 起初我发现我必须改变

public function setServiceLocator(ServiceLocator $sl)

否则我会出错:

setServiceLocator() must be compatible with that of Zend\ServiceManager\ServiceLocatorAwareInterface::setServiceLocator()
调用
$this->getServiceLocator()
时,我得到了FormManager的一个实例。 另外调用
$this->getServiceLocator()->getServiceLocator()
将返回
NULL

因为我还是DI的新手,我想知道我是否错过了一个注射的地方

测试我从

$form = new MyForm();

从那以后,我得到了这个错误:

exception 'Zend\Di\Exception\RuntimeException' with message 'Invalid instantiator of type "NULL" for "Zend\ServiceManager\ServiceLocatorInterface".'
An abstract factory could not create an instance of applicationformmyform(alias: Application\Form\MyForm).
无论如何,不建议使用
ServiceLocator
感知读取一些其他线程。使用
FormElementProviderInterface
是否是替代方法

我以前在课堂上使用过ServiceLocatorAwareInterface,如下所示:

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class MyClass implements ServiceLocatorAwareInterface
{
    protected $services;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->services = $serviceLocator;
    }

    public function getServiceLocator()
    {
        return $this->services;
    }
只需在我的c语言中按服务定位器调用它

$sm = $this->getServiceLocator();
$myClass = $sm->get('Application\Service\MyClass');
无需设置DI。这对于字段集/表单是否必要,以及在何处/如何精确

我尝试以这种方式注入表单和字段集:

    'service_manager' => array(
    'factories' => array(
        'Application\Form\CreateCostcenter' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
            $form = new \Application\Form\CreateCostcenter();
            $form->setServiceLocator($sl);
            return $form;
        },
        'Application\Form\CostcenterFieldset' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
            $fieldset = new \Application\Form\CostcenterFieldset();
            $fieldset->setServiceLocator($sl);
            return $fieldset;
        },
    ),
),
在我的控制器中调用表单时,注入对表单有效:

$form = $this->getServiceLocator()->get('Application\Form\CreateCostcenter');
当然,它不会将serviceManager传递给字段集

无论如何,我不明白为什么ServiceManagerWareness必须有一个配置,因为它只通过实现它就可以与其他类一起工作。 自ZF 2.1以来,文档中也没有关于高级使用的提示:


您是否在servicemanager配置中为表单添加了条目?或者你的DI定义?请看我编辑的这篇文章,谢谢!你把DI配置成这样了吗:你能看看我更新的帖子@Andrew吗?如前所述,我在文档中看到了DI/ServiceLocatorAware的文档。
    'service_manager' => array(
    'factories' => array(
        'Application\Form\CreateCostcenter' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
            $form = new \Application\Form\CreateCostcenter();
            $form->setServiceLocator($sl);
            return $form;
        },
        'Application\Form\CostcenterFieldset' => function (\Zend\ServiceManager\ServiceLocatorInterface $sl) {
            $fieldset = new \Application\Form\CostcenterFieldset();
            $fieldset->setServiceLocator($sl);
            return $fieldset;
        },
    ),
),
$form = $this->getServiceLocator()->get('Application\Form\CreateCostcenter');