Skip to content

Instantly share code, notes, and snippets.

@devnix
Last active September 14, 2023 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devnix/240099c2feede67b153588c858ade9c0 to your computer and use it in GitHub Desktop.
Save devnix/240099c2feede67b153588c858ade9c0 to your computer and use it in GitHub Desktop.
Hexagonal container inspired by PHPStan source code
<?php
declare(strict_types=1);
namespace Shared\Domain\DependencyInjection;
interface ContainerInterface
{
/**
* @return object|null
*
* @deprecated Transition method from Symfony container
* @see self::hasService()
* @see self::getService()
* @see self::getByType()
* @see self::getByNameAndType()
* @see self::getParameters()
* @see self::hasParameter()
* @see self::getParameter()
*/
public function get(string $id);
public function hasService(string $serviceName): bool;
public function getService(string $serviceName): object;
/**
* @phpstan-template T of object
*
* @param class-string<T> $className
*
* @return T
*/
public function getByType(string $className);
/**
* @phpstan-template T of object
*
* @param class-string<T> $className
*
* @return T
*/
public function getByNameAndType(string $serviceName, string $className);
/**
* @return array<array-key, mixed>
*/
public function getParameters(): array;
public function hasParameter(string $parameterName): bool;
/**
* @return mixed
*/
public function getParameter(string $name);
}
<?php
declare(strict_types=1);
namespace Shared\Infrastructure\DependencyInjection;
use function Psl\invariant;
use Psl\Type;
use Shared\Domain\DependencyInjection;
use Symfony;
final class SymfonyContainer implements DependencyInjection\ContainerInterface
{
private Symfony\Component\DependencyInjection\Container $container;
public function __construct(Symfony\Component\DependencyInjection\Container $container)
{
$this->container = $container;
}
/**
* @deprecated
*/
public function get(string $id)
{
return $this->container->get($id);
}
public function hasService(string $serviceName): bool
{
return $this->container->has($serviceName);
}
public function getService(string $serviceName): object
{
try {
$service = $this->container->get($serviceName);
invariant(null !== $service, 'Service %s not found in the container.', $serviceName);
return $service;
} catch (Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException $e) {
throw new DependencyInjection\Exception\ServiceNotFoundException($serviceName, $e);
} catch (\Exception $e) {
throw new \RuntimeException('Unexpected exception', 0, $e);
}
}
public function getByType(string $className)
{
return Type\object($className)->assert($this->getService($className));
}
public function getByNameAndType(string $serviceName, string $className)
{
return Type\object($className)->assert($this->getService($serviceName));
}
public function getParameters(): array
{
return $this->container->getParameterBag()->all();
}
public function hasParameter(string $parameterName): bool
{
return $this->container->hasParameter($parameterName);
}
public function getParameter(string $name)
{
if (!$this->hasParameter($name)) {
throw new DependencyInjection\Exception\ParameterNotFoundException($name);
}
return $this->container->getParameter($name);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment