Enhance Service locator

This commit is contained in:
Eric Espie
2026-01-27 11:54:05 +01:00
parent 390b5c0bc3
commit bfa7a209d6
43 changed files with 338 additions and 210 deletions

View File

@@ -0,0 +1,15 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Service\ServiceLocator;
use Combodo\iTop\Service\ServiceLocator\ServiceLocatorException;
use Psr\Container\NotFoundExceptionInterface;
class NotFoundException extends ServiceLocatorException implements NotFoundExceptionInterface
{
}

View File

@@ -0,0 +1,92 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Service\ServiceLocator;
use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
/**
* @since 3.3.0
*/
class ServiceLocator implements ContainerInterface
{
private array $aServices;
public function __construct()
{
$this->aServices = [];
}
/**
* Register a service by name
*
* @param string $sName Name of the service to register
* @param mixed $oService Service to register
*
* @return void
*/
final protected function RegisterService(string $sName, mixed $oService): void
{
$this->aServices[$sName] = $oService;
}
/**
* Get a previously registered service
*
* @param string $id Service id to search for
*
* @return mixed The service object
* @throws \Combodo\iTop\Service\ServiceLocator\NotFoundException When the service is not configured
* @throws \Combodo\iTop\Service\ServiceLocator\ServiceLocatorException If error during service instanciation
*/
public function get(string $id): mixed
{
if (!isset($this->aServices[$id])) {
throw new NotFoundException("Service ".json_encode($id)." not found");
}
try {
if (is_string($this->aServices[$id])) {
$oService = new $this->aServices[$id]();
$this->aServices[$id] = $oService;
}
} catch (\Throwable $t) {
throw new ServiceLocatorException("Service ".json_encode($id)." not found", $t);
}
return $this->aServices[$id];
}
public function has(string $id): bool
{
return isset($this->aServices[$id]);
}
/**
* Init Service locator for a configuration file corresponding to the category
*
* @see conf/production/service-locator-runtime-config.php
*
* @param string|null $sRelativeConfigFileName config file name relative to APPROOT
*
* @return void
*/
final public function Init(string $sRelativeConfigFileName = null): void
{
if (is_null($sRelativeConfigFileName)) {
$sConfigFile = APPROOT."sources/Service/ServiceLocator/service-locator-runtime-config.php";
} else {
$sConfigFile = APPROOT.$sRelativeConfigFileName;
}
if (!file_exists($sConfigFile)) {
return;
}
$this->aServices = include($sConfigFile);
}
}

View File

@@ -0,0 +1,22 @@
<?php
/*
* @copyright Copyright (C) 2010-2025 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Service\ServiceLocator;
use Exception;
use IssueLog;
use Psr\Container\ContainerExceptionInterface;
use Throwable;
class ServiceLocatorException extends Exception implements ContainerExceptionInterface
{
public function __construct(string $sMessage = '', ?Throwable $oPrevious = null, array $aContext = [])
{
parent::__construct($sMessage, 0, $oPrevious);
IssueLog::Exception(get_class($this).' occurs: '.$sMessage, $this, null, $aContext);
}
}

View File

@@ -0,0 +1,19 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\Dashlet\Service\DashletService;
use Combodo\iTop\Forms\Block\FormBlockService;
use Combodo\iTop\PropertyType\PropertyTypeService;
use Combodo\iTop\Service\Cache\DataModelDependantCache;
return [
'ModelReflection' => ModelReflectionRuntime::class,
'DashletService' => DashletService::class,
'PropertyTypeService' => PropertyTypeService::class,
'DataModelDependantCache' => DataModelDependantCache::class,
'FormBlockService' => FormBlockService::class,
];