ZF2:将特定于操作的配置注入控制器

时间:2013-12-13 21:41:40

标签: php configuration zend-framework2 config

至少有三种方法 - Zend\DiConfigAwareInterfaceControllerFactory - 我已考虑将配置注入控制器。

导致此代码的more or less official recommendation is the ControllerFactory(或this code if you prefer closures - 我没有,因为它们更难测试):

// module.config.php
'controllers' => array (
    'factories' => array (
        'Module\Concept\Index' => 'Concept\ControllerFactory\IndexControllerFactory',
    ),
),
'some_config_key' => array (
    'x' => 'foo'
),

// src/Concept/ControllerFactory/IndexControllerFactory.php
class IndexControllerFactory implements FactoryInterface {
    public function createService(ServiceLocatorInterface $serviceLocator) {
        $config = $serviceLocator->getServiceLocator()->get('config');
        $controller = new \Html\Controller\IndexController($config['some_config_key']);
        return $controller;
    }
}

// src/Concept/Controller/IndexController.php
class IndexController {
    public function __construct($config) {
        // here we go, yay!  we have $config['x'] == 'foo'
    }
}

如果每个动作需要不同的配置(例如,一个可能需要DB,另一个可能需要PayPal),那么仅当某些所有控制器配置似乎不合适行动需要它。

那么,是否需要了解哪种配置进入工厂或进入控制器?也就是说,工厂应该根据手头的动作给控制器仅提供它需要的东西,还是应该给控制器提供所有配置并在内部找出它?

更新
特定于操作的依赖关系就是:特定的。控制器声明它需要什么,然后以任何必要的方式使用它。这两个行动有着截然不同的需求,这表明控制器的范围可能过于广泛,可能是分离的候选者。

但无论如何,最好的方式 - 明确,强大且显然符合ZF未来发展方向的方式 - 是在服务工厂中制造所需的服务,然后制造具有必要服务的控制器。

两个工厂:服务和控制器。控制器声明它与它必须具有的服务的__construct合同,然后工厂根据需要从模块配置制造那些。

1 个答案:

答案 0 :(得分:1)

这个问题主要是基于意见的,所以你可以得到许多不同的答案。

这两种方法都很好,因为:

  • 如您所知,我们在ZF2中看到的很多是服务管理器,所有合并的配置都围绕着所有应用程序运行。因此,即使这不是最好的方法,它也被广泛使用。
  • 如果我们考虑到依赖倒置原则(我们确实有)以及high cohesionlow coupling原则,它们告诉我们隔离是好的,所有组件都没有必须要了解其他两个,并且模块内的所有内容都应该紧密相关,我们可以认为在每个控制器中都有所有合并的配置,甚至让控制器知道关联合并配置数组中的哪个键包含其配置,可能不是最好的东西,也许模块应该接收的是它的配置,无论它来自更大的阵列,来自工厂,来自地狱,还是来自其他地方,因为事实上,它不是需要知道这一点,这无所谓。

因此,最好的方法可能只是注入它期望的配置。实际上,这就是我们在创建ViewHelper时要做的事情,我们通常不会注入所有内容,只会注入我们需要的东西。

这可能会令人困惑,因为有时候你可能还需要一些其他的通用配置,而不仅仅是与模块完全相关的配置,在这种情况下你将不得不考虑它。但在大多数情况下,更优雅的解决方案可能就是注入你需要的东西。

作为一个进一步重要的论点,我在sam minds blog读到了

  

......还有一些事情   只是不理想。一个小例子是许多人使用的   $ this-> getServiceLocator()在他们的控制器中。虽然这没关系,   它实际上被认为是不好的做法。事物的样子   现在,这个功能将在Zend Framework 3(ZF3)中删除   基本上强迫人们使用适当的依赖注入   的ServiceManager。

所以我们可以认为正确的方法是尽可能地引入依赖注入,让每个组件尽可能少地知道。