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

问题描述:

我正在学习ZF2。如何使用getServiceLocator()获取模型中的适配器?

我可以使用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 Framework版本,则不能在控制器类中使用getServiceLocator方法,因为ServiceLocatorAwareInterfaceServiceManagerAwareInterface都被删除。

所以这行:你也许在你的控制器类预期

$sm = $this->getServiceLocator(); 

将无法​​工作。


您还可以在the migration guide阅读更多的这种变化:

以下接口,特点和类被拆除:

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

的ServiceLocatorAware和ServiceManagerAware接口和性状进行了下V2太经常被滥用,并且代表的服务管理器组件的用途的对立面;依赖关系应该直接注入,并且容器不应该由对象组成。

您将需要重构您的服务,可能最好的方法是创建一个服务工厂,在其中注入您的依赖关系。

检查this blog post(章节工厂)关于如何建立工厂的更多细节。

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

例如在你的配置:

'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'); 

这将调用工厂,并带回该模型的完整与适配器。

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