2013-05-14 43 views
0

我的應用程序使用數據映射器模式,所以我有許多映射器類,它們都需要數據庫適配器的一個實例。所以,我的服務配置的factories截面佈滿了條目是這樣的:使用自定義服務定位器減少服務配置重複?

'UserMapper' => function($sm) { 
    $mapper = new UserMapper(); 
    $adapter = $sm->get('Zend\Db\Adapter\Adapter'); 
    $mapper->setAdapter($adapter); 

    return $mapper; 
}, 
'GroupMapper' => function($sm) { 
    $mapper = new GroupMapper(); 
    $adapter = $sm->get('Zend\Db\Adapter\Adapter'); 
    $mapper->setAdapter($adapter); 

    return $mapper; 
}, 

我想去掉一些這方面鍋爐板代碼。我可以爲這些映射器定義一個自定義服務定位器類,它可以通過提供數據庫適配器來實例化任何映射器類,除非定義的工廠配置存在定義嗎?

回答

4

有兩種方法可以解決這個問題。

首先是讓你的映射器實現Zend\Db\Adapter\AdapterAwareInterface,並向服務管理器添加一個初始化器,它將適配器注入到實現該接口的任何服務中。如果你這樣做,所有的映射器都可以放在服務配置的密鑰invokables中,而不是每個都需要一個工廠。然後

的映射器將所有類似於此

<?php 
namespace Foo\Mapper; 

use Zend\Db\Adapter\Adapter; 
use Zend\Db\Adapter\AdapterAwareInterface; 
// if you're using php5.4 you can also make use of the trait 
// use Zend\Db\Adapter\AdapterAwareTrait; 

class BarMapper implements AdapterAwareInterface; 
{ 
    // use AdapterAwareTrait; 

    // .. 
    /** 
    * @var Adapter 
    */ 
    protected $adapter = null; 

    /** 
    * Set db adapter 
    * 
    * @param Adapter $adapter 
    * @return mixed 
    */ 
    public function setDbAdapter(Adapter $adapter) 
    { 
     $this->adapter = $adapter; 

     return $this; 
    } 

} 

在服務管理器的配置,把你的映射器下invokables,並添加一個初始化爲AdapterAware服務

return array(
    'invokables' => array(
     // .. 
     'Foo/Mapper/Bar' => 'Foo/Mapper/BarMapper', 
     // .. 
    ), 
    'initializers' => array(
     'Zend\Db\Adapter' => function($instance, $sm) { 
      if ($instance instanceof \Zend\Db\Adapter\AdapterAwareInterface) { 
       $instance->setDbAdapter($sm->get('Zend\Db\Adapter\Adapter')); 
      } 
     }, 
    ), 
); 

另一種方法是創建一個MapperAbstractServiceFactory,這個答案 - >ZF2 depency injection in parent描述了你可能會這樣做。

+0

謝謝!我會進一步探索這兩個選項 – 2013-05-14 09:39:44

相關問題