Zend framework2 Zend Framework 2 MVC应用程序中的依赖关系管理

Zend framework2 Zend Framework 2 MVC应用程序中的依赖关系管理,zend-framework2,dependency-management,service-locator,zend-form2,zend-framework3,Zend Framework2,Dependency Management,Service Locator,Zend Form2,Zend Framework3,正如ServiceLocatorAwareInterface可能是一样,依赖项应该通过构造函数或setter方法传递 考虑到这一点,考虑用户或站点控制器的用例,如登记、激活帐户、登录、注销等。至少,这将需要UService和2种表单。再添加一些相关的操作(远程身份验证、帐户链接等),最终得到4或5个表单 通过构造函数传递所有这些依赖关系充其量是混乱的,更重要的是,每个操作通常只需要一个表单 您认为以下哪种技术更好,为什么 为每个操作创建单独的控制器,以便每个控制器只需要一个表单(除服务外)。例如

正如ServiceLocatorAwareInterface可能是一样,依赖项应该通过构造函数或setter方法传递

考虑到这一点,考虑用户或站点控制器的用例,如登记、激活帐户、登录、注销等。至少,这将需要UService和2种表单。再添加一些相关的操作(远程身份验证、帐户链接等),最终得到4或5个表单

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

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

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

    • 这样你就有了很多控制器
  • 在控制器的工厂中,根据请求的操作提供不同的表格

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

    • 描述了这种技术
    • 然后,您的控制器将依赖于EventManager而不是ServiceLocator,后者可能不会更好
  • 将FormElementManager传递给控制器,并从中请求表单

    • 很可能不比SL本身好
  • 直接在控制器内构造表单

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

  • 另见:


    首先,不会删除ServiceLocator。也许只是一个服务接口

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

    通过将控制器拆分为更小的控制器,这将使您的代码更干净


    顺便说一句,您谈论的是身份验证,但是如果您正确地插入了身份验证服务(或者将身份验证服务插入到用户服务中或类似的内容中),那么,它显著减少了控制器中的依赖关系。

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

    //用户服务
    公共函数getForm($name,$id=null)
    {
    $form=$this->formRepository->find($name);
    如果($id!==null){
    $entity=$this->entityRepository->find($id);
    $form->bind($entity);
    }
    返回$表格;
    }
    
    我不会将此作为答案发布,但是:1)我认为很多控制器都不是问题。2) 我永远不会这么做。工厂是废弃的逻辑。不要试图检修它。3) maaaaagic-尝试调试它!4) 表单元素管理器是一个ServiceLocator 5)不,我们不再使用了抱歉,我是说ServiceLocator接口,我已经更新了问题。WRT身份验证,我有两个适配器,一个用于本地身份验证,一个用于远程身份验证,因此我需要两个服务,因此也需要两个控制器。表单存储库与FormElementManager有何不同?(仅通过限制可以返回哪些表单?)另外,表单存储库究竟是什么,以及它如何实例化或访问表单?我以前从未见过这种模式。@darkangel我也经常使用这种模式。表单存储库与表单元素管理器不同,因为您可以创建自己的
    User\repository\FormRepository
    类,该类仅实例化2或3个表单。这为表单存储库提供了一个非常特定的范围,并为控制器提供了灵活性。顺便说一句,通常我把“存储库”称为“表单工厂”,这样你会得到一个
    User\factory\FormFactory
    之类的东西。