Zend framework2 使用自定义服务定位器减少服务配置重复?

Zend framework2 使用自定义服务定位器减少服务配置重复?,zend-framework2,datamapper,service-locator,Zend Framework2,Datamapper,Service Locator,我的应用程序使用数据映射器模式,因此我有许多映射器类,每个类都需要一个数据库适配器实例。因此,我的服务配置的factories部分充满了如下条目: 'UserMapper' => function($sm) { $mapper = new UserMapper(); $adapter = $sm->get('Zend\Db\Adapter\Adapter'); $mapper->setAdapter($adapter); return $map

我的应用程序使用数据映射器模式,因此我有许多映射器类,每个类都需要一个数据库适配器实例。因此,我的服务配置的
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;
},

我想删除一些锅炉板代码。我是否可以仅为这些映射器定义一个自定义服务定位器类,它可以通过提供DB适配器实例化任何映射器类,除非存在带有某些自定义工厂配置的定义?

有两种方法可以实现这一点

第一种方法是让映射程序实现
Zend\Db\Adapter\adapterWareInterface
,并向服务管理器添加一个初始值设定项,该初始值设定项将适配器注入实现该接口的任何服务中。如果这样做,所有映射器都可以放在服务配置的
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;
    }

}

另一种方法是创建一个
MapperAbstractServiceFactory
,这个答案->描述了如何实现这一点

有两种方法来解决这个问题

第一种方法是让映射程序实现
Zend\Db\Adapter\adapterWareInterface
,并向服务管理器添加一个初始值设定项,该初始值设定项将适配器注入实现该接口的任何服务中。如果这样做,所有映射器都可以放在服务配置的
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;
    }

}

另一种方法是创建一个
MapperAbstractServiceFactory
,这个答案->描述了如何实现这一点

谢谢!我将探索这两种选择,谢谢!我将进一步探讨这两种选择