据我所知,有效模式是:
问题是,什么是有效/适当的模式 包括/注入其他相互关联的服务?
我们目前非常简化的reallife示例:
AuctionController
/**
* get vehicles for specific auction
*/
public function getVehiclesAction ()
{
$auctionService = $this->getAuctionService(); // via service locator
$auctionID = (int) $this->params('auction-id');
$auction = $auctionService->getAuctionVehicle($auctionID);
return $auction->getVehicles();
}
AuctionService
public function getAuctionVehicles($auctionID) {
$auction = $this->getAuction($auctionID);
// verify auction (active, permissions, ...)
if ($auction) {
$vehicleService = $this->getVehicleService(); // via service locator
$vehicleService->getVehicles($params); // $params = some various conditions or array of IDs
}
return false;
}
VehicleService
public function getVehicles($params) {
$cache = $this->getCache(); // via service locator
$vehicles = $cache->getItem($params);
if (!$vehicles) {
$vehicleDB = $this->getVehicleDB(); // via service locator
$vehicles = $vehicleDB->getVehicles($params);
}
return $vehicles;
}
建议的有效模式示例
AuctionController
public function __construct(AuctionService $auctionService) {
$this->auctionService = $auctionService;
}
/**
* get vehicles for specific auction
*/
public function getVehiclesAction ()
{
$auctionID = (int) $this->params('auction-id');
$auction = $this->auctionService->getAuctionVehicle($auctionID);
return $auction->getVehicles();
}
**AuctionService**
public function getAuctionVehicles($auctionID) {
$auction = $this->getAuction($auctionID); // no problem, local function
// verify auction (active, permissions, ...)
if ($auction) {
$vehicleService = $this->getVehicleService(); // we don't have service locator
$vehicleService->getVehicles($params); // $params = some various conditions or array of IDs
}
return false;
}
VehicleService
public function getVehicles($params) {
$cache = $this->getCache(); // we don't have service locator, but cache is probably static?
$vehicles = $cache->getItem($params);
if (!$vehicles) {
$vehicleDB = $this->getVehicleDB(); // where and how do we get this service
$vehicles = $vehicleDB->getVehicles($params);
}
return $vehicles;
}
一些注意事项:
答案 0 :(得分:5)
如果控制器需要太多不同的服务,通常会指示控制器有太多的责任。
跟进@ AlexP的回答,然后将此服务注入您的控制器。根据您的设置,当创建控制器时,这肯定会导致依赖注入级联。这至少会将创建的服务限制为控制器实际需要的服务(以及那些传递相关的服务)。
如果很少需要其中一些服务,并且您担心每次请求都创建它们,那么新的Service Manager现在也支持lazy services。那些仍然可以作为常规依赖项注入服务/控制器(如上所述),但仅在第一次调用时创建。
从文档示例中复制此内容:
$serviceManager = new \Zend\ServiceManager\ServiceManager([
'factories' => [
Buzzer::class => InvokableFactory::class,
],
'lazy_services' => [
// Mapping services to their class names is required
// since the ServiceManager is not a declarative DIC.
'class_map' => [
Buzzer::class => Buzzer::class,
],
],
'delegators' => [
Buzzer::class => [
LazyServiceFactory::class,
],
],
]);
请求服务时,不会立即创建它:
$buzzer = $serviceManager->get(Buzzer::class);
但只有在第一次使用它时:
$buzzer->buz();
这样,您可以将多个依赖项注入控制器,并且只会创建实际需要的服务。当然,对于任何依赖都是如此,例如其他服务所需的服务等等。
答案 1 :(得分:1)
您可以撰写一项新服务,比如VehicleAuctionService
,并使用工厂将AuctionService
和VehicleService
注入为依赖项。
这是对象组合。
class VehicleAuctionService
{
private $auctionService;
private $vehicleService;
public function __construct(
AuctionService $auctionService,
VehicleService $vehicleService
){
$this->auctionService = $auctionService;
$this->vehicleService = $vehicleService;
}
public function getAuctionVehicles($auctionID)
{
$auction = $this->auctionService->getAuction($auctionID);
if ($auction) {
$params = [
'foo' => 'bar',
];
$this->vehicleService->getVehicles($params);
}
return false;
}
}