【问题标题】:How can I use getServiceLocator() to get an adapter in a Model?如何使用 getServiceLocator() 在模型中获取适配器?
【发布时间】:2017-04-29 22:53:01
【问题描述】:

我正在学习 ZF2。

我可以使用getServiceLocator() 在模型中获取适配器吗?

/config/autoload/global.php

return array(
    'db' => array(
        'driver'         => 'Pdo',
        'dsn'            => 'mysql:dbname=zf2tutorial;host=localhost',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
        'aliases' => array(
            'db' => 'Zend\Db\Adapter\Adapter',
        ),
    ),
);

/config/autoload/local.php

return array(
    'db' => array(
        'username' => 'YOUR USERNAME HERE',
        'password' => 'YOUR PASSWORD HERE',
    ),
);

那么,我该如何使用:

$sm = $this->getServiceLocator();
$this->dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');

在模型中获取适配器?

【问题讨论】:

    标签: zend-framework2 dependencies service-locator servicemanager zend-servicemanager


    【解决方案1】:

    如果您使用的是最新的 Zend Framework 版本,则不能在控制器类中使用 getServiceLocator 方法,因为 ServiceLocatorAwareInterfaceServiceManagerAwareInterface 都已删除。

    所以这一行:

    $sm = $this->getServiceLocator();
    

    在你的控制器类中不会像你预期的那样工作。


    您还可以在the migration guide 中阅读有关此更改的更多信息:

    删除了以下接口、特征和类:

    • ...
    • Zend\ServiceManager\ServiceLocatorAwareInterface
    • Zend\ServiceManager\ServiceLocatorAwareTrait
    • Zend\ServiceManager\ServiceManagerAwareInterface

    ServiceLocatorAware 和 ServiceManagerAware 接口和特征在 v2 下经常被滥用,这与 Service Manager 组件的用途背道而驰;依赖应该直接注入,容器永远不能由对象组成。

    您将需要重构您的服务,并且可能最好的方法是创建一个服务工厂来注入您的依赖项。

    请查看this blog post工厂章节)了解有关如何建造工厂的更多详细信息。

    【讨论】:

      【解决方案2】:

      您需要在创建模型时将适配器注入模型,例如使用工厂。

      例如在您的配置中:

      'service_manager' => array(
          'factories' => array( 
              'Application\Some\Model' => '\Application\Some\ModelFactory'
           )
      )
      

      然后您将创建将适配器注入您的模型的工厂:

      <?php
      namespace Application\Some;
      
      use Zend\ServiceManager\FactoryInterface;
      use Zend\ServiceManager\ServiceLocatorInterface;
      
      class ModelFactory implements FactoryInterface
      {
         /**
           * Create service
           *
           * @param ServiceLocatorInterface $serviceLocator
           * @return mixed
           */
          public function createService(ServiceLocatorInterface $serviceLocator)
          {
               $adapter = $serviceLocator->get('Zend\Db\Adapter\Adapter');
      
               return new Model($adapter);
          }
      }
      

      在这种情况下,您显然需要让您的模型在其构造函数中接受适配器。

      现在,您需要在哪里获取模型实例并注入您要调用的适配器:

      $serviceLocator->get('Application\Some\Model');
      

      这将调用工厂并带回带有适配器的模型。

      然后,您将使用相同的方法将您的模型注入到任何需要它的控制器或服务类中。如前一篇文章所述,尽量避免将服务定位器/服务管理器直接注入到您的对象中,而是使用它从工厂类等中添加您需要的项目(适配器/映射器等)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-12
        • 2018-11-13
        • 2016-01-16
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 2019-02-12
        相关资源
        最近更新 更多