简体   繁体   English

ZF2:Zend Form中的getServiceLocator的等价物

[英]ZF2: Equivalent of getServiceLocator in Zend Form

assumption: Event\\Service\\EventService is my personal object that works with Event\\Entity\\Event entities 假设: Event\\Service\\EventService是我的个人对象,与Event\\Entity\\Event实体一起使用

This code works in an ActionController: 此代码适用于ActionController:

$eventService = $this->getServiceLocator()->get('Event\Service\EventService');

How can I get $eventService in a Zend\\Form\\Form in the same way? 如何以相同的方式在Zend\\Form\\Form中获取$eventService

You have two options if you have a dependency like this. 如果你有这样的依赖,你有两个选择。 In your case, a Form depends on a Service . 在您的情况下, Form取决于Service The first option is to inject dependencies : 第一个选择是注入依赖项

class Form
{
  protected $service;
  public function setService(Service $service)
  {
    $this->service = $service;
  }
}

$form = new Form;
$form->setService($service);

In this case, the $form is unaware of the location of $service and generally accepted as a good idea. 在这种情况下, $form不知道$service的位置,并且通常被认为是一个好主意。 To make sure you don't need to set up all the dependencies yourself each time you need a Form , you can use the service manager to create a factory. 为了确保每次需要Form时都不需要自己设置所有依赖项,可以使用服务管理器创建工厂。

One way (there are more) to create a factory is to add a getServiceConfiguration() method to your module class and use a closure to instantiate a Form object. 创建工厂的一种方法(还有更多)是向模块类添加getServiceConfiguration()方法,并使用闭包来实例化Form对象。 This is an example to inject a Service into a 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;
            }
        )
    );
}

Then you simply get the Form from your service manager. 然后,您只需从服务经理处获取Form即可。 For example, in your controller: 例如,在您的控制器中:

$form = $this->getServiceLocator()->get('Event\Form\Event');

A second option is to pull dependencies . 第二种选择是拉依赖关系 Though it is not recommended for classes like forms, you can inject a service manager so the form can pull dependencies itself: 虽然不建议像表单这样的类,但您可以注入服务管理器,以便表单可以自行提取依赖项:

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

However, this second option couples your code with unnecessary couplings and it makes it very hard to test your code. 但是,第二个选项将您的代码与不必要的耦合耦合在一起,这使得测试代码非常困难。 So please use dependency injection instead of pulling dependencies yourself. 所以请使用依赖注入,而不是自己拉依赖。 There are only a handful of cases where you might want to pull dependencies yourself :) 只有极少数情况下你可能想要自己拉依赖关系:)

You can just configure the form with all the options in the module.php. 您可以使用module.php中的所有选项配置表单。 In the following code I: 在以下代码中我:

  • Name the service as my_form 将服务命名为my_form
  • Associate the new object \\MyModule\\Form\\MyForm with this service 将新对象\\ MyModule \\ Form \\ MyForm与此服务相关联
  • Inject the service 'something1' to the _construct() 将服务'something1'注入_construct()
  • Inject the service 'something2' to the setSomething() 将服务'something2'注入setSomething()

Code: 码:

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

And then in the controller the following line will populate your object with all needed dependencies 然后在控制器中,以下行将使用所有必需的依赖项填充对象

$form = $this->getServiceLocator()->get('my_form');

Use the form element manager to get the form in your controller: 使用表单元素管理器获取控制器中的表单:

  $form = $this->getServiceLocator()->get('FormElementManager')->get('Path\To\Your\Form', $args);

Then in your form will become this 然后在你的形式将成为这个

<?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');
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM