Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection;
|
||||
|
||||
abstract class AbstractBaseContainer implements ContainerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function has($name);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
abstract public function get($name);
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection;
|
||||
|
||||
interface ContainerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed|object
|
||||
*/
|
||||
public function get($name);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection\Definition;
|
||||
|
||||
use Xentral\Core\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
final class FactoryMethodDefinition
|
||||
{
|
||||
/** @var callable $callable */
|
||||
private $callable;
|
||||
|
||||
/** @var bool $shared Share the same instance? */
|
||||
private $shared;
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
* @param bool $shared
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($callable, $shared = true)
|
||||
{
|
||||
if (!is_callable($callable, false)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Definition can\'t be created. "%s::%s" is not callable.', $callable[0], $callable[1]
|
||||
));
|
||||
}
|
||||
|
||||
$this->callable = $callable;
|
||||
$this->shared = (bool)$shared;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return callable
|
||||
*/
|
||||
public function getCallable()
|
||||
{
|
||||
return $this->callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isShared()
|
||||
{
|
||||
return $this->shared;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection\Exception;
|
||||
|
||||
use Xentral\Core\Exception\CoreExceptionInterface;
|
||||
|
||||
interface ContainerExceptionInterface extends CoreExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection\Exception;
|
||||
|
||||
use InvalidArgumentException as SplInvalidArgumentException;
|
||||
|
||||
class InvalidArgumentException extends SplInvalidArgumentException implements ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ServiceNotFoundException extends RuntimeException implements ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Core\DependencyInjection;
|
||||
|
||||
final class ServiceContainer extends AbstractBaseContainer
|
||||
{
|
||||
/** @var ServiceRegistry $registry */
|
||||
private $registry;
|
||||
|
||||
/**
|
||||
* @param ServiceRegistry $registry
|
||||
*/
|
||||
public function __construct(ServiceRegistry $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return $this->registry->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed|object
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
return $this->registry->get($name);
|
||||
}
|
||||
}
|
||||
@@ -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