Skip to content

Commit

Permalink
ContainerBuilder: Implemented automatic resolution of parameters [Closes
Browse files Browse the repository at this point in the history
 #4]
  • Loading branch information
enumag authored and dg committed Aug 15, 2014
1 parent 6aa6ca0 commit a1f48d0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/DI/ContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,23 @@ private function resolveImplement(ServiceDefinition $def, $name)
}

if (!$def->parameters) {
$ctorParams = array();

This comment has been minimized.

Copy link
@TomasVotruba

TomasVotruba Aug 15, 2014

Contributor

"ctor" stands for "constructor"? I need to read getConstructor() bellow to understand (if so) and faCTORy on line right bellow confuses my guessing till then.

I'd prefer full name in this case as it might be misleading. What do you think?

This comment has been minimized.

Copy link
@Majkl578

Majkl578 Aug 15, 2014

Contributor

I'm ok with ctor, it's commonly used shortcut (and constructorParams is kinda long).

This comment has been minimized.

Copy link
@TomasVotruba

TomasVotruba Aug 15, 2014

Contributor

Ok, it was my first time seeing this. I'll remember it then :)

if ($def->factory && !$def->factory->arguments && ($class = $this->resolveEntityClass($def->factory, array($name => 1)))
&& ($ctor = Reflection\ClassType::from($class)->getConstructor())
) {
foreach ($ctor->getParameters() as $param) {
$ctorParams[$param->getName()] = $param;
}
}

foreach ($method->getParameters() as $param) {
if (isset($ctorParams[$param->getName()])) {
$arg = $ctorParams[$param->getName()];
if ($param->getClassName() !== $arg->getClassName() || $param->isArray() !== $arg->isArray()) {
throw new ServiceCreationException("Type hint for $arg doesn't match type hint for $param");
}
$def->factory->arguments[$arg->getPosition()] = ContainerBuilder::literal('$' . $arg->getName());
}
$paramDef = ($param->isArray() ? 'array' : $param->getClassName()) . ' ' . $param->getName();
if ($param->isOptional()) {
$def->parameters[$paramDef] = $param->getDefaultValue();
Expand Down
33 changes: 33 additions & 0 deletions tests/DI/Compiler.generatedFactory.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,36 @@ Assert::type('IArticleFactory', $container->getService('article2'));
$article = $container->getService('article2')->create('nemam');
Assert::type('Article', $article);
Assert::same('nemam', $article->title);


Assert::type( 'IFooFactory', $container->getService('fooFactory3') );
$foo = $container->getService('fooFactory3')->create($container->getService('baz'));
Assert::type( 'Foo', $foo );
Assert::type( 'Bar', $foo->bar );
Assert::same($container->getService('bar'), $foo->bar);
Assert::type( 'Baz', $foo->baz );
Assert::same($container->getService('baz'), $foo->baz);
$foo = $container->getService('fooFactory3')->create();
Assert::type( 'Foo', $foo );
Assert::type( 'Bar', $foo->bar );
Assert::same($container->getService('bar'), $foo->bar);
Assert::null( $foo->baz );


class Bad1
{
public function __construct(Bar $bar)
{
}
}

interface Bad2
{
public function create(Baz $bar);
}

Assert::exception(function() {
$builder = new DI\ContainerBuilder;
$builder->addDefinition('one')->setImplement('Bad2')->setFactory('Bad1');
$builder->generateClasses();
}, 'Nette\InvalidStateException', "Type hint for \$bar in Bad1::__construct() doesn't match type hint for \$bar in Bad2::create()");
4 changes: 4 additions & 0 deletions tests/DI/files/compiler.generatedFactory.neon
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ services:
create: Foo(..., %baz%)
implement: IFooFactory
parameters: [Baz baz = NULL]

fooFactory3:
create: Foo
implement: IFooFactory

3 comments on commit a1f48d0

@vojtech-dobes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big things today :). 👍

@hrach
Copy link
Contributor

@hrach hrach commented on a1f48d0 Aug 15, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@fprochazka
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh

Please sign in to comment.