【问题标题】:Why is the Servicemanager injected in a invokable and not a service为什么Servicemanager注入可调用而不是服务
【发布时间】:2013-10-26 05:59:19
【问题描述】:

我目前正在使用 ZF2 serviceManager,我试图弄清楚为什么 serviceManager 不将 sm 注入到实现 ServiceLocatorAwareInterface 的类中。

我的主要问题是我做得对还是“服务”键不是针对实现 ServiceLocatorAwareInterface 的服务而是针对不需要注入的服务?

在 Module.php 中

public function getServiceConfig() {
    return array(
        'invokables' => array(
            'myService1' => 'MyModule\Service\Service'
        ),
        'services' => array(
            'myService2' => new MyModule\Service\Service(),
        ),
    );
}

在 MyModule\Service\Service.php 中

namespace MyModule\Service;

use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;

class Service implements ServiceManagerAwareInterface
{
    /**
     * @var ServiceManager
     */
    protected $serviceManager = NULL;

    /**
     * Retrieve service manager instance
     *
     * @return ServiceManager
     */
    public function getServiceManager()
    {
        return $this->serviceManager;
    }

    /**
     * Set service manager instance
     *
     * @param ServiceManager $serviceManager
     */
    public function setServiceManager(ServiceManager $serviceManager)
    {
        $this->serviceManager = $serviceManager;
    }
}

当我在控制器中调用服务时

<?php

namespace MyModule\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{

    public function IndexAction() {

        $service1   = $this->getServiceLocator()->get('myService1');
        $sm1        = $service1->getServiceManager(); 
        //$sm1 becomes a object of Zend\ServiceManager\ServiceManager
        //In other words i now can access the SM from within my service.

        $service2   = $this->getServiceLocator()->get('myService2');
        $sm2        = $service2->getServiceManager(); 
        //$sm2 becomes NULL
        //The service isn't aware of the SM and can't access it.

    }

}

【问题讨论】:

  • 首先阅读文档如何使用服务管理器。你做错了/
  • 提示:您注入了完整的实例化服务,这意味着依赖关系在其他地方处理。
  • @Xerkus...哈哈,这是 zf 文档的精确副本。我只是想知道为什么 sm1 是而 sm2 没有得到 sm ..
  • @Xerkus 另外,当我自动使用 ServiceManagerAwareInterface 时,zf2 不会为我注入任何东西,正如 zf2 文档中指出的那样,我将引用“默认情况下,Zend Framework MVC 注册一个初始化程序这会将作为 Zend\ServiceManager\ServiceLocatorInterface 实现的 ServiceManager 实例注入到任何实现 Zend\ServiceManager\ServiceLocatorAwareInterface 的类中。” framework.zend.com/manual/2.0/en/modules/…

标签: php zend-framework2


【解决方案1】:

如果您想使用 ServiceManagerAwareInterface 并将 Service Manager 自动注入到您的服务中,您应该继续使用“invokables”部分。

查看/Zend/ServiceManager/ServiceManager.php,“服务”意味着注册为ServiceManager 中已经实例化的对象。当服务定位器在检索期间在其本地服务缓存中查找时,它假定“服务”已经完全设置并且不注入 sm 或运行任何初始化程序。

“invokables”、“factories”、“abstract_factories”是动态创建的,并在“initializers”在新创建的服务实例上运行时注入 sm(参见函数 create($name))。

【讨论】:

【解决方案2】:

忘记 getServiceConfig() 并改用您的模块配置。它更快且可缓存:

module.config.php

'service_manager' => array(
    'invokables' => array(
        'MyModule\Service\Service' => 'MyModule\Service\Service',
    ),
)

MyModule\Service\Service.php

<?php
namespace MyModule\Service;

use \Zend\ServiceManager\ServiceLocatorInterface;

class Service
{
    public function __invoke(ServiceLocatorInterface $sm)
    {
        // go bananas here :)
    }

    public functiom greet()
    {
        return 'Hello World';
    }
}

zend2 中的任何地方

<?php
    $service=$serviceManager->get('MyModule\Service\Service');
    echo $service->greet();

【讨论】:

  • 如何在 ervice` 类中获取 ServiceManager 的实例?
  • 我上面的代码真的很老很糟糕。您根本不应该使用服务管理器。您可以在网上找到更多关于 ZF2 中的依赖注入的信息。
猜你喜欢
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
相关资源
最近更新 更多