Skip to content

Commit

Permalink
Container::$meta divided to $services, $aliases, $types & $tags (BC b…
Browse files Browse the repository at this point in the history
…reak)
  • Loading branch information
dg committed Dec 6, 2018
1 parent 5387e87 commit c298a5b
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 61 deletions.
12 changes: 5 additions & 7 deletions src/Bridges/DITracy/ContainerPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,12 @@ public function getPanel(): string
$registry = $this->getContainerProperty('registry');
$file = (new \ReflectionClass($container))->getFileName();
$tags = [];
$meta = $this->getContainerProperty('meta');
$services = $meta[Container::SERVICES];
$types = $this->getContainerProperty('types');
$services = $this->getContainerProperty('services');
ksort($services);
if (isset($meta[Container::TAGS])) {
foreach ($meta[Container::TAGS] as $tag => $tmp) {
foreach ($tmp as $service => $val) {
$tags[$service][$tag] = $val;
}
foreach ($this->getContainerProperty('tags') as $tag => $tmp) {
foreach ($tmp as $service => $val) {
$tags[$service][$tag] = $val;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Bridges/DITracy/templates/ContainerPanel.panel.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use Tracy\Helpers;
<tbody>
<?php foreach ($services as $name => $type): ?>
<?php $name = (string) $name ?>
<?php $autowired = !empty($meta[Nette\DI\Container::TYPES][$type][true]) && in_array($name, $meta[Nette\DI\Container::TYPES][$type][true], true) ?>
<?php $autowired = !empty($types[$type][true]) && in_array($name, $types[$type][true], true) ?>
<tr>
<td class="<?= isset($registry[$name]) ? 'created' : '' ?>"><?= htmlspecialchars($name) ?></td>
<td class="<?= $autowired ? 'yes' : '' ?>"><?= $autowired ? 'yes' : 'no' ?></td>
Expand Down
53 changes: 27 additions & 26 deletions src/DI/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@ class Container
{
use Nette\SmartObject;

public const TAGS = 'tags';

public const TYPES = 'types';
/** @var array user parameters */
public $parameters = [];

public const SERVICES = 'services';
/** @var string[] */
protected $services = [];

public const ALIASES = 'aliases';
/** @var string[] */
protected $aliases = [];

/** @var array user parameters */
public $parameters = [];
/** @var array[] */
protected $types = [];

/** @var array[] */
protected $meta = [];
protected $tags = [];

/** @var object[] storage for shared objects */
private $registry = [];
Expand Down Expand Up @@ -62,15 +63,15 @@ public function addService(string $name, $service)
if (!$name) {
throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.', gettype($name)));
}
$name = $this->meta[self::ALIASES][$name] ?? $name;
$name = $this->aliases[$name] ?? $name;
if (isset($this->registry[$name])) {
throw new Nette\InvalidStateException("Service '$name' already exists.");

} elseif (!is_object($service)) {
throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be a object, %s given.", $name, gettype($service)));

} elseif (isset($this->meta[self::SERVICES][$name]) && !$service instanceof $this->meta[self::SERVICES][$name]) {
throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be instance of %s, %s given.", $name, $this->meta[self::SERVICES][$name], get_class($service)));
} elseif (isset($this->services[$name]) && !$service instanceof $this->services[$name]) {
throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be instance of %s, %s given.", $name, $this->services[$name], get_class($service)));
}

$this->registry[$name] = $service;
Expand All @@ -83,7 +84,7 @@ public function addService(string $name, $service)
*/
public function removeService(string $name): void
{
$name = $this->meta[self::ALIASES][$name] ?? $name;
$name = $this->aliases[$name] ?? $name;
unset($this->registry[$name]);
}

Expand All @@ -96,8 +97,8 @@ public function removeService(string $name): void
public function getService(string $name)
{
if (!isset($this->registry[$name])) {
if (isset($this->meta[self::ALIASES][$name])) {
return $this->getService($this->meta[self::ALIASES][$name]);
if (isset($this->aliases[$name])) {
return $this->getService($this->aliases[$name]);
}
$this->registry[$name] = $this->createService($name);
}
Expand All @@ -111,11 +112,11 @@ public function getService(string $name)
*/
public function getServiceType(string $name): string
{
if (isset($this->meta[self::ALIASES][$name])) {
return $this->getServiceType($this->meta[self::ALIASES][$name]);
if (isset($this->aliases[$name])) {
return $this->getServiceType($this->aliases[$name]);

} elseif (isset($this->meta[self::SERVICES][$name])) {
return $this->meta[self::SERVICES][$name];
} elseif (isset($this->services[$name])) {
return $this->services[$name];

} else {
throw new MissingServiceException("Service '$name' not found.");
Expand All @@ -128,7 +129,7 @@ public function getServiceType(string $name): string
*/
public function hasService(string $name): bool
{
$name = $this->meta[self::ALIASES][$name] ?? $name;
$name = $this->aliases[$name] ?? $name;
return isset($this->registry[$name])
|| (method_exists($this, $method = self::getMethodName($name))
&& (new \ReflectionMethod($this, $method))->getName() === $method);
Expand All @@ -143,7 +144,7 @@ public function isCreated(string $name): bool
if (!$this->hasService($name)) {
throw new MissingServiceException("Service '$name' not found.");
}
$name = $this->meta[self::ALIASES][$name] ?? $name;
$name = $this->aliases[$name] ?? $name;
return isset($this->registry[$name]);
}

Expand All @@ -155,7 +156,7 @@ public function isCreated(string $name): bool
*/
public function createService(string $name, array $args = [])
{
$name = $this->meta[self::ALIASES][$name] ?? $name;
$name = $this->aliases[$name] ?? $name;
$method = self::getMethodName($name);
if (isset($this->creating[$name])) {
throw new Nette\InvalidStateException(sprintf('Circular reference detected for services: %s.', implode(', ', array_keys($this->creating))));
Expand Down Expand Up @@ -189,8 +190,8 @@ public function createService(string $name, array $args = [])
public function getByType(string $type, bool $throw = true)
{
$type = Helpers::normalizeClass($type);
if (!empty($this->meta[self::TYPES][$type][true])) {
if (count($names = $this->meta[self::TYPES][$type][true]) === 1) {
if (!empty($this->types[$type][true])) {
if (count($names = $this->types[$type][true]) === 1) {
return $this->getService($names[0]);
}
natsort($names);
Expand All @@ -210,9 +211,9 @@ public function getByType(string $type, bool $throw = true)
public function findByType(string $type): array
{
$type = Helpers::normalizeClass($type);
return empty($this->meta[self::TYPES][$type])
return empty($this->types[$type])
? []
: array_merge(...array_values($this->meta[self::TYPES][$type]));
: array_merge(...array_values($this->types[$type]));
}


Expand All @@ -222,7 +223,7 @@ public function findByType(string $type): array
*/
public function findByTag(string $tag): array
{
return $this->meta[self::TAGS][$tag] ?? [];
return $this->tags[$tag] ?? [];
}


Expand Down
10 changes: 5 additions & 5 deletions src/DI/ContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,19 @@ public function getDependencies(): array
*/
public function exportMeta(): array
{
$meta[Container::TYPES] = $this->autowiring->getClassList();
$meta['types'] = $this->autowiring->getClassList();

$defs = $this->definitions;
ksort($defs);
foreach ($defs as $name => $def) {
$meta[Container::SERVICES][$name] = $def->getType();
$meta['services'][$name] = $def->getType();
foreach ($def->getTags() as $tag => $value) {
$meta[Container::TAGS][$tag][$name] = $value;
$meta['tags'][$tag][$name] = $value;
}
}

$meta[Container::ALIASES] = $this->aliases;
ksort($meta[Container::ALIASES]);
$meta['aliases'] = $this->aliases;
ksort($meta['aliases']);

return $meta;
}
Expand Down
8 changes: 5 additions & 3 deletions src/DI/PhpGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ public function generate(string $className): Nette\PhpGenerator\ClassType
->addParameter('params', [])
->setTypeHint('array');

$class->addProperty('meta')
->setVisibility('protected')
->setValue($this->builder->exportMeta());
foreach ($this->builder->exportMeta() as $key => $value) {
$class->addProperty($key)
->setVisibility('protected')
->setValue($value);
}

$definitions = $this->builder->getDefinitions();
ksort($definitions);
Expand Down
4 changes: 2 additions & 2 deletions tests/DI/Compiler.arguments.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Assert::error(function () use (&$container) {
- method( [Lorem, method], 'Lorem::add', Lorem::add )
- method( not(true) )
- method( @lorem::var, @self::var, @container::parameters )
- method( @lorem::DOLOR_SIT, @self::DOLOR_SIT, @container::TAGS )
- method( @lorem::DOLOR_SIT, @self::DOLOR_SIT )
dolor:
factory: Lorem(::MY_FAILING_CONSTANT_TEST)
Expand Down Expand Up @@ -86,4 +86,4 @@ Assert::same([false], $lorem->args[4]);
Assert::same([$lorem->var, $lorem->var, $container->parameters], $lorem->args[5]);

// service constant
Assert::same([Lorem::DOLOR_SIT, Lorem::DOLOR_SIT, DI\Container::TAGS], $lorem->args[6]);
Assert::same([Lorem::DOLOR_SIT, Lorem::DOLOR_SIT], $lorem->args[6]);
36 changes: 27 additions & 9 deletions tests/DI/Compiler.services.tags.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ use Tester\Assert;
require __DIR__ . '/../bootstrap.php';


function getPropertyValue($obj, string $name)
{
$prop = (new \ReflectionObject($obj))->getProperty($name);
$prop->setAccessible(true);
return $prop->getValue($obj);
}


$compiler = new DI\Compiler;
$container = createContainer($compiler, '
services:
Expand All @@ -25,22 +33,32 @@ services:
');


$prop = (new ReflectionClass($container))->getProperty('meta');
$prop->setAccessible(true);

Assert::same([
'types' => [
Assert::same(
[
Nette\DI\Container::class => [1 => ['container']],
'stdClass' => [1 => ['lorem']],
],
'services' => ['container' => Nette\DI\Container::class, 'lorem' => 'stdClass'],
'tags' => [
getPropertyValue($container, 'types')
);

Assert::same(
['container' => Nette\DI\Container::class, 'lorem' => 'stdClass'],
getPropertyValue($container, 'services')
);

Assert::same(
[
'a' => ['lorem' => true],
'b' => ['lorem' => 'c'],
'd' => ['lorem' => ['e']],
],
'aliases' => [],
], $prop->getValue($container));
getPropertyValue($container, 'tags')
);

Assert::same(
[],
getPropertyValue($container, 'aliases')
);

Assert::same(['lorem' => true], $container->findByTag('a'));
Assert::same([], $container->findByTag('x'));
15 changes: 7 additions & 8 deletions tests/DI/Container.getServiceType.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ require __DIR__ . '/../bootstrap.php';

class MyContainer extends Container
{
protected $meta = [
'services' => [
'one' => 'One',
'two' => 'Two',
],
'aliases' => [
'three' => 'one',
],
protected $services = [
'one' => 'One',
'two' => 'Two',
];

protected $aliases = [
'three' => 'one',
];
}

Expand Down

0 comments on commit c298a5b

Please sign in to comment.