php - 在没有 serviceLocator->get() 方式的情况下,ZF2 中新的依赖注入(inject)方式是否更加低效?

标签 php dependency-injection zend-framework2 overhead zend-framework3

zend-mvc 的 2.7.0 版开始ServiceLocatorAwareInterface 已删除, Controller 内部的 $this->serviceLocator->get() 调用也是如此。

这就是为什么几天前我对我的所有模块进行了一次巨大的重构,以通过使用工厂的构造函数注入(inject)所需的服务/对象。

当然,我理解为什么这是更好/更干净的做事方式,因为依赖关系现在更加可见。但另一方面:

这会导致沉重的开销和更多从未使用过的类实例,不是吗?

让我们看一个例子:

因为我所有的 Controller 都有依赖关系,所以我为它们都创建了工厂。

CustomerControllerFactory.php

namespace Admin\Factory\Controller;
class CustomerControllerFactory implements FactoryInterface {
    public function createService(ServiceLocatorInterface $controllerManager) {
        $serviceLocator = $controllerManager->getServiceLocator();
        $customerService = $serviceLocator->get('Admin\Service\CustomerService');
        $restSyncService = $serviceLocator->get('Admin\Service\SyncRestClientService');

        return new \Admin\Controller\CustomerController($customerService, $restSyncService);
    }
}

CustomerController.php

namespace Admin\Controller;

class CustomerController extends AbstractRestfulController {
    public function __construct($customerService, $restSyncService) {
        $this->customerService = $customerService;
        $this->restSyncService = $restSyncService;
    }
}

module.config.php

'controllers' => [
  'factories' => [
    'Admin\Controller\CustomerController' => 'Admin\Factory\Controller\CustomerControllerFactory',
  ]
],
'service_manager' => [
  'factories' => [
    'Admin\Service\SyncRestClientService' => 'Admin\Factory\SyncRestClientServiceFactory',
  ]
]

SyncRestClientServiceFactory.php

namespace Admin\Factory;
class SyncRestClientServiceFactory implements FactoryInterface {
    public function createService(ServiceLocatorInterface $serviceLocator) {
        $entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default');
        $x1 = $serviceLocator->get(...);
        $x2 = $serviceLocator->get(...);
        $x3 = $serviceLocator->get(...);
        // ...

        return new \Admin\Service\SyncRestClientService($entityManager, $x1, $x2, $x3, ...);
    }
}

SyncRestService 是一个复杂的服务类,它查询我们系统的一些内部服务器。它有很多依赖关系,并且总是在请求到达 CustomerController 时创建。但是此同步服务在CustomerController 的syncAction() 中使用!在我只是在 syncAction() 中使用 $this->serviceLocator->get('Admin\Service\SyncRestClientService') 之前,所以它才被实例化。

一般来说,看起来很多实例是在每次请求时通过工厂创建的,但大多数依赖项没有被使用。这是我的设计造成的问题,还是“通过构造函数进行依赖注入(inject)”的正常副作用行为?

最佳答案

在我看来,这是通过构造函数进行依赖注入(inject)的正常效果。

我认为您现在有两个选项(不是相互排斥的)来改进您的应用程序的工作方式:

  1. 拆分您的 Controller ,以便仅在需要时实例化依赖项。这肯定会产生更多的类、更多的工厂等等,但是您的代码会更符合单一职责原则

  2. 你可以使用 Lazy Services , 因此,即使某些服务是整个 Controller 的依赖项,它们实际上只会在第一次被调用时被实例化(所以永远不会在没有调用它们的操作中被实例化!)

关于php - 在没有 serviceLocator->get() 方式的情况下,ZF2 中新的依赖注入(inject)方式是否更加低效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36796060/

相关文章:

php - 尝试使用 PHP 将带有 UNICODE 代码的 JSON 字符串转换为 UTF8

php - mysqli_free_result 有必要吗?

c# - 依赖注入(inject)IOption类库

php - laravel 多选表单获取数组

php - 查询结果显示为“0”

javascript - AngularJS:将 Controller 注入(inject)同一模块中的另一个 Controller

java - 当尝试注入(inject) spring-quartz 作业时,@Autowired 字段中有 null 吗?

pagination - 如何在 Zend Framework 2 中实现搜索模块的分页?

php - 来自没有 Controller 的模块的 ZF2 配置

zend-form - ZF2,如何创建表单 View 助手?