ZF2 服务定位器 [英] ZF2 Service Locator

查看:34
本文介绍了ZF2 服务定位器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 zf2 很陌生,我正在试验它.我有一个视图助手,我需要它来访问表对象.在我的控制器中,我可以运行:

I'm quite new to zf2 and I'm experimenting with it. I have a view helper and I need it to access a table object. In my controller I can run:

$this->getServiceLocator();

但理想情况下,我会在我的视图助手中运行它.不幸的是,我似乎无法从我的视图助手中访问它.我尝试通过构造函数传递它,在 module.config.php 中配置工厂方法,但是当我尝试这样做时,Zend 将不再将 tablegateway 对象传递到我从模块模块中的服务工厂方法创建的模型对象之一.php 文件.这似乎是因为它不再调用工厂方法,而是选择不带任何参数运行instantiate.

But ideally I would run this inside my view helper. Unfortunately, I can't seem to access it from within my view helper. I tried passing it through the constructor, configuring a factory method in module.config.php, but when I try that, Zend will no longer pass a tablegateway object into one of my model objects created from a service factory method in the module's Module.php file. This seems to be because it no longer calls the factory method, and opts to run instantiate without any parameters.

我不确定我是否理解为什么视图工厂方法会影响具有不同名称的不同工厂方法集.

I'm not certain I understand why the view factory methods would affect a different set of factory methods with different names.

谁能告诉我我做的事情有什么问题?我可以提供更多细节,但目前我不清楚哪些细节实际上很重要,但不提供整个代码库.

Can anyone tell me what is wrong with what I'm doing? I can provide more details, but at this point I'm unclear on what details are actually important without supplying the entire codebase.

谢谢.

推荐答案

Crisp 确实为您的问题提供了有效的答案,但我建议更进一步.服务定位器的注入使您的视图助手与框架和服务定位器模式紧密耦合并且容易受到攻击,因为应用程序中的每一段代码都可以修改服务定位器中的每个服务.

Crisp does provide a valid answer to your question, but I would suggest to take it one step further. The injection of the service locator makes your view helper tightly coupled to the framework and service locator pattern and vulnerable because every piece of code inside your application can modify every service in the service locator.

有理由直接注入您的依赖项,因此您只依赖于您的依赖项,并且不再实施此反模式.假设您的视图助手依赖于 MyModule\Model\MyTable,那么您的视图助手的构造函数将如下所示:

There are reasons to inject your dependency directly, so you only depend on your dependencies and you're not implementing this anti-pattern anymore. Let's assume your view helper depends on MyModule\Model\MyTable, then the constructor of your view helper would just look like this:

namespace MyModule;

use MyModule\Model\MyTable;
use Zend\View\Helper\AbstractHelper;

class MyViewHelper extends AbstractHelper
{
  protected $table;

  public function __construct(MyTable $table)
  {
    $this->table = $table;
  }
}

正如您所指出的,您现在只需注入 MyTable:

As you pointed out, you just inject your MyTable now:

namespace MyModule;

class Module
{
  public function getViewHelperConfig()
  {
    return array(
      'factories' => array(
        'MyViewHelper' => function($sm) {
          $sm = $sm->getServiceLocator(); // $sm was the view helper's locator
          $table = $sm->get('MyModule_MyTable');

          $helper = new MyModule\View\Helper\MyHelper($table);
          return $helper;
        }
      )
    );
  }
}

请注意,在视图助手工厂中,您的服务管理器是视图助手 的服务管理器,而不是注册表的主要"服务管理器(另请参见 我之前写的博文).$sm->getServiceLocator() 为您解决了这个问题.

Note that inside a view helper factory your service manager is the view helper's service manager and not the "main" one where the table is registered (see also a blog post of I wrote earlier). The $sm->getServiceLocator() solves this for you.

我不确定我是否理解为什么视图工厂方法会影响具有不同名称的不同工厂方法集.

I'm not certain I understand why the view factory methods would affect a different set of factory methods with different names.

不是,所以您的代码中可能存在错误.如果以上方法不起作用,请提供有关您的服务管理器配置的更多详细信息,以便我可以更新我的答案.

It's not, so there is probably a bug in your code. If above does not work, please provide some more details on your service manager configuration so I can update my answer.

上述方法的一大优点是您可以让您的视图助手非常轻松地进行单元测试.您可以模拟表网关并专注于视图助手的完整行为.

One of the great advantages of above approach is you make unit testing really easy for your view helper. You can mock the table gateway and focus on the complete behaviour of your view helper.

use MyModule\View\Helper\MyHelper;

public function testHelperusesTable
{
  $mock   = $this->getMock('MyModule\Model\MyTable');
  $helper = new MyHelper($mock);

  // Test your $helper now
}

这篇关于ZF2 服务定位器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆