Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
autowiring via Service[] (#178)
  • Loading branch information
dg committed Oct 23, 2018
1 parent 854867d commit 61ab15c
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/DI/Autowiring.php
Expand Up @@ -189,6 +189,16 @@ public static function completeArguments(\ReflectionFunctionAbstract $method, ar
$optCount = 0;
}

} elseif (
$container instanceof Resolver
&& $method instanceof \ReflectionMethod
&& $parameter->isArray()
&& preg_match('#@param[ \t]+([\w\\\\]+)\[\][ \t]+\$' . $paramName . '#', (string) $method->getDocComment(), $m)
&& ($type = Reflection::expandClassName($m[1], $method->getDeclaringClass()))
&& (class_exists($type) || interface_exists($type))
) {
$res[$num] = $container->findByType($type);

} elseif (($type && $parameter->allowsNull()) || $parameter->isOptional() || $parameter->isDefaultValueAvailable()) {
// !optional + defaultAvailable = func($a = null, $b) since 5.4.7
// optional + !defaultAvailable = i.e. Exception::__construct, mysqli::mysqli, ...
Expand Down
68 changes: 68 additions & 0 deletions tests/DI/ContainerBuilder.autowiring.type[].phpt
@@ -0,0 +1,68 @@
<?php

/**
* Test: Nette\DI\ContainerBuilder and typehint Service[].
*/

declare(strict_types=1);

use Nette\DI;
use Tester\Assert;


require __DIR__ . '/../bootstrap.php';


class Foo
{
public $bars;
public $foos;
public $strings;


/**
* @param Service[] $bars
* @param Foo[] $foos
* @param string[] $strings
*/
public function __construct(array $bars = [], array $foos = null, array $strings = ['default'])
{
$this->bars = $bars;
$this->foos = $foos;
$this->strings = $strings;
}
}

class Service
{
}

class ServiceChild extends Service
{
}


$builder = new DI\ContainerBuilder;

$builder->addDefinition('foo')
->setType('Foo');
$builder->addDefinition('s1')
->setType('Service');
$builder->addDefinition('s2')
->setType('Service');
$builder->addDefinition('s3')
->setType('ServiceChild');
$builder->addDefinition('s4')
->setType('stdClass');

$container = createContainer($builder);

$foo = $container->getService('foo');
Assert::type(Foo::class, $foo);
Assert::same([
$container->getService('s1'),
$container->getService('s2'),
$container->getService('s3'),
], $foo->bars);
Assert::same([], $foo->foos);
Assert::same(['default'], $foo->strings);

0 comments on commit 61ab15c

Please sign in to comment.