2016-08-22 88 views
0

我在閱讀關於Service Manager的Zend 3文檔,並且遇到了這個問題。在Zend3中使用服務管理器的正確方法

在文檔它說,如果我們在我們的控制器有一些DI我們應該更新module.config.php文件,並添加控制器鍵調用控制器不InvokableFactory::class而是使用自定義工廠類和添加包含類陣列的另一個關鍵service_manager,我的第一個控制器使用。

好了,所以我這樣做:

module.config.php

'service_manager' => [ 
     'factories' => [ 
      Controller\Controller2::class => Factory\Controller2Factory::class, 
      Controller\Controller3::class => Factory\Controller3Factory::class, 
     ], 
    ], 
'controllers' => [ 
     'factories' => [ 
      Controller\Controller1::class => Factory\Controller1Factory::class 
     ], 
    ] 

Controller1Factory.php

class Controller1Factory implements FactoryInterface 
{ 
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
    { 
     return new Controller1(
      $container->get(Controller2::class), 
      $container->get(Controller3::class), 
     ); 
    } 
} 

但現在我有錯誤控制器2和Controller3也有DI在其建設者,所以我做新的自定義工廠等等...直到我到我的模型。

模型也有依賴注入在他們的控制器是zend原生\Zend\Db\TableGateway\TableGatewayInterface,我現在必須再次編輯我的conf文件並添加TableGatewayInterface

這是錯誤的。我絕不應該被迫以這種方式注入本地zend類和服務。

那麼我做錯了什麼?

+0

目前尚不清楚問題是什麼。你說你的模型_require_要注入到它們的構造函數中,但是你不希望被迫使用服務管理器注入類。 (如果是這樣,你會喜歡什麼方法?) –

+0

@TimFountain那麼我的模型需要\ Zend \ Db \ TableGateway \ TableGatewayInterface實例,我將它注入到我的模型的構造函數中。但是,因爲這是zend接口,我不確定在特定接口的服務管理器中插入新值是否合適。 – madeye

+0

您不應該將控制器注入控制器。爲每個具有模型依賴關係的控制器創建一個單獨的工廠類,並注入每個需要的模型。 – dualmon

回答

1

如果你的控制器沒有依賴關係,那麼最好的方法是像你一樣在module.config.php中聲明它。

但是,如果它有依賴關係,最好在Module.php。你首先聲明你的服務,那麼控制器(不要忘記從module.config.php刪除它),在其注入所依賴的服務:

public function getServiceConfig() 
{ 
    return [ 
     'factories' => [ 
      Model\MyObjectTable::class => function($container) { 
       $tableGateway = $container->get(Model\MyObjectTableGateway::class); 
       return new Model\MyObjectTable($tableGateway); 
      }, 
      Model\MyObjectTableGateway::class => function($container) { 
       $dbAdapter = $container->get(AdapterInterface::class); 
       $resultSetPrototype = new ResultSet(); 
       $resultSetPrototype->setArrayObjectPrototype(new Model\User()); 
       return new TableGateway('myObject', $dbAdapter, null, $resultSetPrototype); 
      }, 
     ] 
    ]; 
} 

public function getControllerConfig() 
{ 
    return [ 
     'factories' => [ 
      Controller\MyObjectController::class => function($container) { 
       return new Controller\MyObjectController(
        $container->get(Model\MyObjectTable::class) 
       ); 
      }, 
     ] 
    ]; 
} 

而在你的控制器:

private $table; 

public function __construct(MyObjectTable $table) 
{ 
    $this->table = $table ; 
} 

這是描述在This ZF3 tutorial page and following

+1

對工廠使用閉包不是一個好主意。它不能被操作碼緩存,並且合併的配置數組不能被緩存。對於生產用途,您應該始終制造具體的工廠,然後在模塊配置工廠部分中引用該工廠。 – dualmon

+1

@dualmon這是Zend在「專輯」導師中實現它的方式。但在「深度」導師中,他們按照你的說法行事。我也在學習ZF3,你的評論讓我想到用具體的工廠重寫我的應用程序。謝謝。 –

+0

也許一旦你解決了問題,也可以更新你的答案?然後我可以放棄它。 – dualmon

相關問題