簡體   English   中英

ZF3:ServiceNotFoundException並在ServiceManager中注冊抽象工廠創建類時

[英]ZF3: ServiceNotFoundException while creating a class with Abstract Factory registered in ServiceManager

我對“ 抽象工廠”示例有疑問

使用在ServiceManager中注冊的Abstract Factory創建類時,出現ServiceNotFoundException

首先,我使用composer下載zend-servicemanager

composer require zendframework/zend-servicemanager

然后,我在單個文件中運行ServiceManager示例(為簡單起見)。

<?php
require_once 'vendor/autoload.php';

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\ServiceManager\Factory\AbstractFactoryInterface;

應該通過ServiceManager獲取的類。

class A
{
    public $text;

    public function __construct() 
    {
        $this->text = "Default text";
    }
}

我從文檔中使用MyAbstractFactory。

class MyAbstractFactory implements AbstractFactoryInterface
{
  public function canCreate(ContainerInterface $container, $requestedName)
  {
    return in_array('Traversable', class_implements($requestedName), true);
  }

  public function __invoke(ContainerInterface $container, 
                           $requestedName,
                           array $options = null)
  {
    return $requestedName();
  }
}

我用注冊的抽象工廠創建ServiceManager。

$serviceManager = new ServiceManager([
    // Neither works    
  //'abstract_factories' => array('MyAbstractFactory')
  'abstract_factories' => array( new MyAbstractFactory() )
  //'abstract_factories' => array( MyAbstractFactory::class )
  /*  
    'abstract_factories' => [
        MyAbstractFactory::class => new MyAbstractFactory()
    ]
  */  
]);

最后,我嘗試獲取類A的實例。

$a = $serviceManager->get(A::class);
var_dump($a);

我收到Fatal error: Uncaught Zend\\ServiceManager\\Exception\\ServiceNotFoundException: Unable to resolve service "A" to a factory; are you certain you provided it during configuration? Fatal error: Uncaught Zend\\ServiceManager\\Exception\\ServiceNotFoundException: Unable to resolve service "A" to a factory; are you certain you provided it during configuration? 與堆棧跟蹤

.\vendor\zendframework\zend-servicemanager\src\ServiceManager.php(763): Zend\ServiceManager\ServiceManager->getFactory('A') #1
.\vendor\zendframework\zend-servicemanager\src\ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('A') #2
.\script.php(53): Zend\ServiceManager\ServiceManager->get('A') #3

我對這個問題的表述是錯誤的。 @rkeet的評論很清楚。

由於我的目標是在ServiceManager中進行抽象工廠注冊的工作示例,因此我發布了單文件腳本,其中canCreate()得以簡化,只是為了檢查該類是否存在。

<?php
// composer require zendframework/zend-servicemanager

require_once 'vendor/autoload.php';

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\AbstractFactoryInterface;


class A
{
    public $text;

    public function __construct() 
    {
        $this->text = "Default text";
    }
}


class MyAbstractFactory implements AbstractFactoryInterface
{
    public function canCreate(ContainerInterface $container, $requestedName)
    {
        return class_exists($requestedName);
    }

    public function __invoke(ContainerInterface $container, 
                             $requestedName,
                             array $options = null)
    {
        return new $requestedName();
    }
}


$serviceManager = new ServiceManager([
  //'abstract_factories' => array('MyAbstractFactory') // works
  //'abstract_factories' => array( new MyAbstractFactory() ) // works
  'abstract_factories' => array( MyAbstractFactory::class ) // also works
]);


try {
    $a = $serviceManager->get(A::class);
    var_dump($a);
    echo "<br/>\n";
    $b = $serviceManager->get(B::class);
    var_dump($b);
} catch (Exception $e) {
    echo $e->getMessage() . "<br/>\n";
    echo "{$e->getFile()}  ({$e->getLine()})";
}
?>

正如@rkeet所指出的,如果有人需要原始示例工作,則A類應實現Traversable

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM