如何使用getServiceLocator()获取模型中的适配器?

时间:2016-12-14 14:49:23

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

我正在学习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');

在模型中获取适配器?

2 个答案:

答案 0 :(得分: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');

这将调用工厂并使用适配器恢复模型。

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

答案 1 :(得分:0)

如果您使用的是最新的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(章工厂),详细了解如何建立工厂。

相关问题