Skip to content

Commit

Permalink
autowiring via Service[] (experimental)
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Oct 3, 2018
1 parent e27629b commit 9144555
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/DI/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ public static function autowireArguments(\ReflectionFunctionAbstract $method, ar
$optCount = 0;
}

} elseif (
$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] = array_values($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
64 changes: 64 additions & 0 deletions tests/DI/ContainerBuilder.autowiring.type[].phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?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 $services;
public $strings;


/**
* @param Service[] $services
* @param string[] $strings
*/
public function __construct(array $services = [], array $strings = ['default'])
{
$this->services = $services;
$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->services);
Assert::same(['default'], $foo->strings);

0 comments on commit 9144555

Please sign in to comment.