【问题标题】:Dependency management in Zend Framework 2 MVC applicationsZend Framework 2 MVC 应用程序中的依赖管理
【发布时间】:2013-10-29 00:08:03
【问题描述】:

由于 ServiceLocatorAwareInterface 可能是 removed from the AbstractController in ZF3,因此应该通过构造函数或 setter 方法传递依赖关系。

考虑到这一点,请考虑用户或站点控制器的用例,其中包含注册、激活帐户、登录、注销等操作。这至少需要一个 UserService 和 2 个表单。添加更多相关操作(远程身份验证、帐户链接等),您最终会得到 4 或 5 个表单。

通过构造函数传递所有这些依赖关系充其量是混乱的,更重要的是,每个操作通常只需要一个表单。

您认为以下哪种技术更好,为什么?

  1. 为每个操作创建单独的控制器,以便每个控制器只需要一个表单(除了服务之外)。例如RegistrationController、LoginController、LinkAccountController等

    • 您最终会以这种方式获得大量控制器。
  2. 在控制器的工厂中,根据请求的操作提供不同的表单。

    • 控制器的构造依赖于这个工厂,更具体地说是请求环境(路由等)。您可以直接构造控制器(用于测试或其他),但是您需要确保依赖关系可用否则抛出异常。
  3. 使用事件管理器,在需要表单时触发控制器中的事件,让事件处理程序按需提供依赖。

    • 这种技术被描述为here
    • 然后,您的控制器将依赖于 EventManager 而不是 ServiceLocator,这可能不会好多少。
  4. 将 FormElementManager 传递给控制器​​,并从中请求表单。

    • 很可能不会比 SL 本身更好。
  5. 直接在控制器内部构造表单。

    • 这对可测试性有何影响?
    • 同样的问题也适用于处理具有多个服务(而不是表单)的控制器。
  6. 其他?

另见:

【问题讨论】:

  • 我不会将此作为答案发布,但是:1) 我不认为很多控制器是个问题。 2)永远不会这样做。工厂是废品逻辑。不要试图对其进行大修。 3) maaaaagic - 尝试调试它! 4) 表单元素管理器 IS 是一个 ServiceLocator 5) 不,我们远离了它

标签: zend-framework2 dependency-management service-locator zend-form2 zend-framework3


【解决方案1】:

首先,ServiceLocator 不会被删除。也许只是 ServiceLocatorAwareInterface。

正如您所说,传递 FormElementManager 是一种解决方案,它确实比传递服务定位器更好。我个人使用越来越多的插件管理器,它们是解决这类问题的好方法。插件管理器与服务定位器不同,因为它只允许检索一种类型的对象(表单、水合器、输入过滤器......)。当然,由于父服务定位器被注入到插件管理器中,有些人会从插件管理器中检索服务定位器(这就是为什么我想在 ZF3 中删除插件管理器中的服务定位器,而是使用一个传递父定位器进行注入的特定工厂,尽管它会使工厂接口复杂一点:/...)。

这样,将控制器拆分成更小的控制器,应该会让你的代码更简洁。

顺便说一句,您正在谈论身份验证,但imo如果您正确地注入了身份验证服务(或将身份验证服务注入到用户服务或类似的东西中),它会显着减少对控制器的依赖。

【讨论】:

  • 对不起,我的意思是 ServiceLocatorAwareInterface,我已经更新了问题。 WRT 身份验证,我有两个适配器,一个用于本地身份验证,一个用于远程身份验证,所以我需要两个服务,因此也需要两个控制器。
【解决方案2】:

您需要考虑作为一个域来解决的问题。在用户域中,有多种形式。因此,将它们聚合到存储库中。表单存储库将与其他存储库(如实体存储库)一起传递给用户服务。然后将用户服务传递到控制器中。

// UserService
public function getForm($name, $id = null)
{
    $form = $this->formRepository->find($name);
    if ($id !== null) {
        $entity = $this->entityRepository->find($id);
        $form->bind($entity);
    }
    return $form;
}

【讨论】:

  • 表单存储库与 FormElementManager 有何不同? (只是通过限制可以返回哪些表单?)另外,表单存储库到底是什么,它如何实例化或访问表单?我以前没见过这种模式。
  • @darkangel 我也经常使用这种模式。表单存储库与表单元素管理器不同,因为您可以创建自己的 User\Repository\FormRepository 类,它只实例化 2 或 3 个表单。这为您的表单存储库提供了一个非常具体的范围,并为您的控制器提供了灵活性。顺便提一句。通常我将“存储库”称为“表单工厂”,因此您会得到 User\Factory\FormFactory 或其他名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
相关资源
最近更新 更多