Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection;
|
||||
|
||||
use Xentral\Components\Logger\LoggerAwareTrait;
|
||||
use Xentral\Core\DependencyInjection\Definition\FactoryMethodDefinition;
|
||||
use Xentral\Core\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Xentral\Core\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
final class ServiceRegistry extends AbstractBaseContainer
|
||||
{
|
||||
/** @var array $services Storage for service instances */
|
||||
private $services = [];
|
||||
|
||||
/** @var FactoryMethodDefinition[] $factories Storage for factory methods */
|
||||
private $factories = [];
|
||||
|
||||
/**
|
||||
* @param array $factoryMethods
|
||||
*/
|
||||
public function __construct(array $factoryMethods = [])
|
||||
{
|
||||
$this->addFactories($factoryMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return $this->hasService($name) || $this->hasFactory($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @throws ServiceNotFoundException
|
||||
*
|
||||
* @return object|mixed
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if ($this->hasService($name)) {
|
||||
return $this->services[$name];
|
||||
}
|
||||
|
||||
if ($this->hasFactory($name)) {
|
||||
$definition = $this->factories[$name];
|
||||
$factoryMethod = $definition->getCallable();
|
||||
$serviceInstance = $factoryMethod($this->get('ServiceContainer'));
|
||||
//inject Logger if required
|
||||
if (
|
||||
$this->has('Logger')
|
||||
&& in_array(LoggerAwareTrait::class, class_uses($serviceInstance), true)
|
||||
) {
|
||||
/** @var LoggerAwareTrait $serviceInstance */
|
||||
$serviceInstance->setLogger($this->get('Logger'));
|
||||
}
|
||||
|
||||
// Don't save non-shared services
|
||||
if (!$definition->isShared()) {
|
||||
return $serviceInstance;
|
||||
}
|
||||
|
||||
// Save shared services
|
||||
$this->add($name, $serviceInstance);
|
||||
|
||||
return $this->services[$name];
|
||||
}
|
||||
|
||||
throw new ServiceNotFoundException(sprintf(
|
||||
'Service "%s" was not found.', $name
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param object $instance
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function add($name, $instance)
|
||||
{
|
||||
if (!is_object($instance)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'%s could not be added. Only objects can be added to container.', $name
|
||||
));
|
||||
}
|
||||
|
||||
$this->services[$name] = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFactory($name)
|
||||
{
|
||||
return isset($this->factories[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param callable $callable
|
||||
* @param bool $shared
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function addFactory($name, $callable, $shared = true)
|
||||
{
|
||||
if (!is_callable($callable, true)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Factory "%s" can not be added. Second argument must be a callable.', $name
|
||||
));
|
||||
}
|
||||
|
||||
if (!is_string($name)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Factory "%s" can not be added. Factory name must be a string.', $name
|
||||
));
|
||||
}
|
||||
|
||||
if ($this->hasFactory($name)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Factory "%s" can not be added. Factory is already present.', $name
|
||||
));
|
||||
}
|
||||
|
||||
$this->factories[$name] = new FactoryMethodDefinition($callable, $shared);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|\Iterator $factories
|
||||
*/
|
||||
public function addFactories($factories)
|
||||
{
|
||||
foreach ($factories as $name => $callable) {
|
||||
$this->addFactory($name, $callable, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasService($name)
|
||||
{
|
||||
return isset($this->services[$name]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user