2014-10-11 15 views
0

我在ZF2中真正不喜歡的是Controller知道存儲引擎(這明顯違反了SRP),並且存儲引擎的概念是Tables。我認爲這是不正確的方式,和控制器應該只知道服務的(而只有服務應該知道存儲引擎)如何將getAlbumTable()放入服務中?

class AlbumController extends AbstractActionController 
{ 
    protected $albumTable; 

    public function getAlbumTable() 
    { 
     if (!$this->albumTable) { 
      $sm = $this->getServiceLocator(); 
      $this->albumTable = $sm->get('Album\Model\AlbumTable'); 
     } 
     return $this->albumTable; 
    } 
手動

無處我可以找到如何將它放入一個服務和使控制器只知道行動。 你會如何把它變成服務?

回答

2

我知道這是官方教程中的做法,但在我看來這不是最好的方法。相反,你想通過你的依賴關係注入你的控制器類。它的構造函數。這使得更容易看到發生了什麼,並且更容易測試。

要做到這一點,修改控制器類增加一個合適的構造函數:

class AlbumController extends AbstractActionController 
{ 
    protected $albumTable; 

    public function __construct(AlbumTable $albumTable) 
    { 
     $this->albumTable = $albumTable; 
    } 
} 

然後,取出可調用線在你module.config.php這個控制器,因爲它不再僅僅是沒有任何實例參數。相反,您可以定義工廠告訴ZF如何實例化類。在您的Module.php

use Zend\Mvc\Controller\ControllerManager; 
use Album\Controller\AlbumController; 

class Module 
{ 
    public function getControllerConfig() 
    { 
     return array(
      'factories' => array(
       'Album\Controller\Album' => function(ControllerManager $cm) { 
        $sm = $cm->getServiceLocator(); 
        $albumTable = $sm->get('Album\Model\AlbumTable'); 

        $controller = new AlbumController($albumTable); 

        return $controller; 
       }, 
      ), 
     ); 
    } 
} 

(或者你可以創建一個單獨的工廠類做到這一點。)

在你的控制器動作,那麼你可以通過訪問該專輯表。 $this->albumTable而不是$this->getAlbumTable()

希望你可以看到,這種方法可以很容易地修改爲注入服務類。如果你想把你的專輯表注入到服務中,並將服務注入到控制器中;你可能最終是這樣的:

class Module 
{ 
    public function getServiceConfig() 
    { 
     return array(
      'factories' => array(
       'Album\Model\AlbumTable' => function($sm) { 
        $tableGateway = $sm->get('AlbumTableGateway'); 
        $table = new AlbumTable($tableGateway); 
        return $table; 
       }, 
       'AlbumTableGateway' => function($sm) { 
        [etc...] 
       }, 
       'Album\Service\AlbumService' => function($sm) { 
        $albumTable = $sm->get('Album\Model\AlbumTable'); 

        return new AlbumService($albumTable); 
       } 
      ), 
     ); 
    } 

    public function getControllerConfig() 
    { 
     return array(
      'factories' => array(
       'Album\Controller\Album' => function(ControllerManager $cm) { 
        $sm = $cm->getServiceLocator(); 
        $albumService = $sm->get('Album\Service\AlbumService'); 

        $controller = new AlbumController($albumService); 

        return $controller; 
       }, 
      ), 
     ); 
    } 
} 

控制器:

class AlbumController extends AbstractActionController 
{ 
    protected $albumService; 

    public function __construct(AlbumService $albumService) 
    { 
     $this->albumService = $albumService; 
    } 

    public function someAction() 
    { 
     // do stuff with $this->albumService 
    } 
} 
相關問題