ZF2:Zend Form中的getServiceLocator的等价物

chr*_*ala 2 php dependency-injection zend-framework2

假设:Event\Service\EventService我的个人对象是与Event\Entity\Event实体一起使用的

此代码适用于ActionController:

$eventService = $this->getServiceLocator()->get('Event\Service\EventService');
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到$eventService一个Zend\Form\Form以同样的方式?

Jur*_*man 5

如果你有这样的依赖,你有两个选择.在你的情况下,a Form取决于a Service.第一个选择是注入依赖项:

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

$form = new Form;
$form->setService($service);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,$form它不知道$service一个好主意的位置,并且通常被认为是一个好主意.要确保每次需要时都不需要自己设置所有依赖项Form,可以使用服务管理器创建工厂.

创建工厂的一种方法(还有更多)是向getServiceConfiguration()模块类添加方法并使用闭包来实例化Form对象.这是注入一个示例ServiceForm:

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;
            }
        )
    );
}
Run Code Online (Sandbox Code Playgroud)

然后,您只需Form从服务经理处获取.例如,在您的控制器中:

$form = $this->getServiceLocator()->get('Event\Form\Event');
Run Code Online (Sandbox Code Playgroud)

第二种选择是拉依赖关系.虽然不建议像表单这样的类,但您可以注入服务管理器,以便表单可以自行提取依赖项:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,第二个选项将您的代码与不必要的耦合耦合在一起,这使得测试代码非常困难.所以请使用依赖注入而不是自己拉依赖.只有极少数情况下你可能想要自己拉依赖关系:)