我想从控制器调用方法SteeringWheelMapper-> fetchCarBrandList()。 这现在很好用,但是有一个问题。
SteeringWheelMapper扩展了AbstractWebServiceMapper,它有一个构造方法,需要一个\ Zend \ Http \ Client实例。
正如您在我的module.config.php文件中看到的,我使用“工厂”来实例化我的SteeringWheelMapper。 供应商有多个产品,因此我将不得不构建多个映射器。在目前的情况下,这意味着我必须为扩展AbstractWebServiceMapper的每个映射器的工厂配置添加一个键。
例如,当我想添加ExhaustMapper时,我必须添加
SupplierName\Mapper\Exhaust => function ($serviceMapper) {
$httpClient => new \Zend\Http\Client;
return new SupplierName\Mapper\ExhaustMapper($httpClient);
}
现在我正在重复自己,因为我还必须为SupplierName \ Mapper \ SteeringWheelMapper执行此操作。
我认为应该有办法为所有映射器创建一个工厂,而不是添加到工厂配置中的新密钥。 我的想法是对的吗? 有没有人建议我该怎么做?
请参阅以下代码。
我正在使用ZF2并使用此设置: /供应商
SupplierName
$ steeringWheelMapper = $ this-> getServiceLocator() - > get('SupplierName \ Mapper \ SteeringWheel'); $ carBrandList = $ steeringWheelMapper-> fetchCarBrandsList();
SteeringWheelMapper.php
<?php
namespace SupplierName\Mapper;
class SteeringWheelMapper extends AbstractWebServiceMapper
{
public function fetchCarBrandList()
{
// Code for request
// Dispatch HTTP request
$this->dispatch();
}
}
我的SupplierName / config / module.config.php如下所示:
<?php
return array(
'service_manager' => array(
'factories' => array(
'SupplierName\Mapper\SteeringWheel' => function ($serviceManager) {
$httpClient = new \Zend\Http\Client;
return new SupplierName\Mapper\SteeringWheelMapper($httpClient);
},
),
),
'supplier_name' => array(
'api' => array(
'url' => 'http://api.example.com',
),
'log' => array(
'file_location' => __DIR__ . '/../log/log.log',
),
),
);
答案 0 :(得分:1)
你实际谈论的是一个抽象工厂,服务经理支持这个概念,但是你需要自己编写,这里有一个例子,假设所有的地图制作者都以SupplierName\Mapper
开头
<?php
namespace SupplierName\Services;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class MapperAbstractFactory implements AbstractFactoryInterface
{
public function canCreateServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
{
if (0 === strpos($requestedName, 'SupplierName\\Mapper') && class_exists($requestedName)){
return true;
}
return false;
}
public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
{
$httpClient = new \Zend\Http\Client;
return new $requestedName($httpClient);
}
}
在你的服务配置中,添加一个抽象工厂密钥,以及抽象工厂的fqcn,希望每当你调用$sm->get('SupplierName\Mapper\SomeClass');
提供类时,你都会得到一个返回的组合实例
public function getServiceConfig()
{
return array(
'abstract_factories' => array(
'SupplierName\Services\MapperAbstractFactory'
),
);
}
答案 1 :(得分:1)
最终工作解决方案:
<?php
// module/Application/src/Application/Controller/IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\I18n\Translator\Translator;
class IndexController extends AbstractActionController
{
protected $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function indexAction()
{
$steeringWheelMapper = $this->getServiceLocator()->get('SupplierName\Mapper\SteeringWheel');
$carBrandList = $steeringWheelMapper->fetchCarBrandList();
return new ViewModel();
}
<?php
// vendor/SupplierName/src/SupplierName/Module.php
namespace SupplierName;
class Module
{
public function getConfig()
{
return include __DIR__ . '/../../config/module.config.php';
}
public function getServiceConfig()
{
return array(
'abstract_factories' => array(
'SupplierName\Mapper\MapperAbstractFactory'
),
);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__,
),
),
);
}
<?php
// vendor/SupplierName/src/SupplierName/Mapper/SteeringWheelMapper.php
namespace SupplierName\Mapper;
class SteeringWheelMapper extends AbstractWebServiceMapper
{
public function fetchCarBrandList()
{
$this->dispatch();
}
}
<?php
// vendor/SupplierName/src/SupplierName/Mapper/AbstractWebServiceMapper.php
namespace SupplierName\Mapper;
use \Zend\Http\Client;
class AbstractWebServiceMapper
{
public function __construct(Client $client)
{
}
public function dispatch()
{
}
<?php
// vendor/SupplierName/src/SupplierName/Mapper/MapperAbstractFactory.php
namespace SupplierName\Mapper;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use \Zend\Http\Client;
class MapperAbstractFactory implements AbstractFactoryInterface
{
public function canCreateServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
{
if (0 === strpos($requestedName, 'SupplierName\Mapper')) {
$requestedName .= 'Mapper';
if (class_exists($requestedName)) {
return true;
}
}
return false;
}
public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
{
$requestedName .= 'Mapper';
$httpClient = new Client();
return new $requestedName($httpClient);
}
}