1

AbstractPluginManager有一个有趣的属性称为$autoAddInvokableClass,启用后,它会自动将您尝试调用的任何类添加到它的可调用列表中。不幸的是,据我所知,这种行为不是由 ServiceManager 本身实现的。

在应用程序的 ServiceManager 中实现此行为的最佳方法是什么,即使没有注册它$applicationServiceManager->get(SomeUnregisteredClass::class)也会加载,因此仍然在对象上运行任何相关的初始化程序?SomeUnregisteredClass$applicationServiceManager

尝试在不注册的情况下执行此操作SomeUnregisteredClass通常会引发类似于以下内容的异常。

Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get 无法获取或创建 SomeUnregisteredClass 的实例

4

1 回答 1

3

首先,请意识到您使用此功能创造的所有可能性:您真的需要这个吗?

然后,“根”服务管理器没有autoAddInvokableClass属性。但是,您可以创建自己的服务管理器并将其注册为默认服务管理器。

创建您的自定义:

<?php
namespace MyLib\ServiceManager;

use Zend\ServiceManager as BaseServiceManager;

class ServiceManager extends BaseServiceManager
{
    protected $autoAddInvokableClass = true;

    public function get($name, $options = array(), $usePeeringServiceManagers = true)
    {
        // Allow specifying a class name directly; registers as an invokable class
        if (!$this->has($name) && $this->autoAddInvokableClass && class_exists($name)) {
            $this->setInvokableClass($name, $name);
        }

        return parent::get($name, $options, $usePeeringServiceManagers);
    }
}

请注意,所有服务管理器都将从这个扩展,包括控制器加载器。因此,如果您有一条路线,您可以在参数中指定 FQCN 时以这种方式/foo/:controller[/:action]加载任何:controller类!

无论如何,话虽如此,只需在您的应用程序配置中启用此 SM:

<?php
return array(
    'modules' => array(
        'Application',
        // Your module here
    ),

    'module_listener_options' => array(
        'module_paths' => array(
            './module',
            './vendor',
        ),
        'config_glob_paths' => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
    ),

    // Used to create an own service manager. May contain one or more child arrays.
    'service_listener_options' => array(
        array(
            'service_manager' => 'MyLib\ServiceManager\ServiceManager',
        ),
    ),
);
于 2013-09-01T09:24:46.463 回答