Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge 847b385 into c33367f
Browse files Browse the repository at this point in the history
  • Loading branch information
noopable committed Oct 16, 2015
2 parents c33367f + 847b385 commit e8d4024
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/Di.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,14 @@ public function get($name, array $params = [])
array_pop($this->instanceContext);
return $im->getSharedInstanceWithParameters(null, [], $fastHash);
}
}

if ($im->hasSharedInstance($name, $callParameters)) {
if (!$this->definitions->hasClass($name) && $im->hasSharedInstance($name)) {
array_pop($this->instanceContext);
return $im->getSharedInstance($name);
}
} elseif ($im->hasSharedInstance($name)) {
array_pop($this->instanceContext);
return $im->getSharedInstance($name, $callParameters);
return $im->getSharedInstance($name);
}

$config = $im->getConfig($name);
Expand Down
2 changes: 1 addition & 1 deletion src/InstanceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ protected function createHashForValues($classOrAlias, $paramValues)
$hashValue .= $param . '|';
break;
case 'array':
$hashValue .= 'Array|';
$hashValue .= $this->createHashForValues($classOrAlias, $param) . '|';
break;
case 'resource':
$hashValue .= 'resource|';
Expand Down
121 changes: 121 additions & 0 deletions test/DiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,41 @@ public function testGetWithParamsWillUseSharedInstance()
$this->assertInstanceOf($retrievedInstanceClass, $returnedC);
}

/**
*
* @group 4714
* @group SharedInstanceWithParameters
*/
public function testGetWithParamsWillUseSharedInstanceWithParameters()
{
$di = new Di;

$sharedInstanceClass = 'ZendTest\Di\TestAsset\ConstructorInjection\A';
$retrievedInstanceClass = 'ZendTest\Di\TestAsset\ConstructorInjection\C';

// Provide definitions for $retrievedInstanceClass, but not for $sharedInstanceClass.
$arrayDefinition = [$retrievedInstanceClass => [
'supertypes' => [ ],
'instantiator' => '__construct',
'methods' => ['__construct' => true],
'parameters' => [ '__construct' => [
"$retrievedInstanceClass::__construct:0" => ['a', $sharedInstanceClass, true, null],
"$retrievedInstanceClass::__construct:1" => ['params', null, false, []],
]],
]];

// This also disables scanning of class A.
$di->setDefinitionList(new DefinitionList(new Definition\ArrayDefinition($arrayDefinition)));

// and we can get a new instance with parameters
$di->instanceManager()->addSharedInstanceWithParameters(new $sharedInstanceClass, $sharedInstanceClass, ['params' => ['test']]);
$di->instanceManager()->addSharedInstanceWithParameters(new $sharedInstanceClass, $sharedInstanceClass, ['params' => ['alter']]);
$returnedC = $di->get($retrievedInstanceClass, ['params' => ['test']]);
$returnedAltC = $di->get($retrievedInstanceClass, ['params' => ['alter']]);
$this->assertNotSame($returnedC, $returnedAltC);
$this->assertEquals(['alter'], $returnedAltC->params);
}

public function testGetInstanceWithParamsHasSameNameAsDependencyParam()
{
$config = new Config([
Expand Down Expand Up @@ -1017,4 +1052,90 @@ public function testGetInstanceWithParamsHasSameNameAsDependencyParam()
$di = new Di(null, null, $config);
$this->assertCount(1, $di->get('ZendTest\Di\TestAsset\AggregatedParamClass')->aggregator->items);
}

/**
*
* test protected method Di::resolveMethodParameters
* for constructor injection
*
* @dataProvider providesResolveMethodParameters
* @group 4714
* @group 6388
*/
public function testResolveMethodParameters($param, $expected)
{
$config = [
'instance' => [
'preference' => [
TestAsset\ConstructorInjection\A::class => TestAsset\ConstructorInjection\E::class,
],
],
];
$di = new Di(null, null, new Config($config));
$ref = new \ReflectionObject($di);
$method = $ref->getMethod('resolveMethodParameters');
$method->setAccessible(true);

//user provides alias name
$im = $di->instanceManager();
$im->addAlias('foo', TestAsset\ConstructorInjection\F::class, ['params' => ['p' => 'vFoo']]);
$im->addAlias('bar', TestAsset\ConstructorInjection\F::class, ['params' => ['p' => 'vBar']]);

$args = [
TestAsset\ConstructorInjection\B::class,
'__construct',
$param, //without parameters
null,
Di::METHOD_IS_CONSTRUCTOR,
true
];
$res = $method->invokeArgs($di, $args);
$this->assertInstanceOf($expected, $res[0]);
}

/**
*
* Provides parameters for protected method Di::resolveMethodParameters
*
* @group 4714
* @group 6388
*/
public function providesResolveMethodParameters()
{
return [
'resolve as type preferenced class @group 6388' => [[], TestAsset\ConstructorInjection\E::class],
'resolve class user provided (not E)' => [['a' => TestAsset\ConstructorInjection\F::class], TestAsset\ConstructorInjection\F::class],
'resolve alias class @group 4714' => [['a' => 'foo'], TestAsset\ConstructorInjection\F::class],
];
}

/**
* constructor injection consultation
*
* @group 4714
*/
public function testAliasesWithDeffrentParams()
{
$config = [
'instance' => [
'preference' => [
TestAsset\ConstructorInjection\A::class => TestAsset\ConstructorInjection\E::class,
],
],
];
$di = new Di(null, null, new Config($config));
$im = $di->instanceManager();
$im->addAlias('foo', TestAsset\ConstructorInjection\F::class, ['params' => ['p' => 'vfoo']]);
$im->addAlias('bar', TestAsset\ConstructorInjection\F::class, ['params' => ['p' => 'vbar']]);

$pref = $di->get(TestAsset\ConstructorInjection\B::class);
$bFoo = $di->get(TestAsset\ConstructorInjection\B::class, ['a' => 'foo']);
$bBar = $di->get(TestAsset\ConstructorInjection\B::class, ['a' => 'bar']);
$this->assertInstanceOf(TestAsset\ConstructorInjection\E::class, $pref->a);
$this->assertNotSame($pref->a, $bFoo->a);
$this->assertInstanceOf(TestAsset\ConstructorInjection\F::class, $bFoo->a);
$this->assertInstanceOf(TestAsset\ConstructorInjection\F::class, $bBar->a);
$this->assertEquals('vfoo', $bFoo->a->params['p']);
$this->assertEquals('vbar', $bBar->a->params['p']);
}
}
28 changes: 28 additions & 0 deletions test/InstanceManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,32 @@ public function testInstanceManagerResolvesRecursiveAliasesForConfig()

$this->assertEquals($config, $im->getConfig('foo-alias'));
}

public function testInstanceManagerCanPersistInstancesWithArrayParameters()
{
$im = new InstanceManager();
$obj1 = new TestAsset\BasicClass();
$obj2 = new TestAsset\BasicClass();
$obj3 = new TestAsset\BasicClass();

$im->addSharedInstance($obj1, 'foo');
$im->addSharedInstanceWithParameters($obj2, 'foo', ['foo' => ['bar']]);

$this->assertSame($obj1, $im->getSharedInstance('foo'));
$this->assertSame($obj2, $im->getSharedInstanceWithParameters('foo', ['foo' => ['bar']]));
$this->assertFalse($im->hasSharedInstanceWithParameters('foo', ['foo' => []]));

$im->addSharedInstanceWithParameters($obj3, 'foo', ['foo' => ['baz']]);

$this->assertSame($obj2, $im->getSharedInstanceWithParameters('foo', ['foo' => ['bar']]));
$this->assertSame($obj3, $im->getSharedInstanceWithParameters('foo', ['foo' => ['baz']]));
}

public function testInstanceManagerCanPersistInstanceWithArrayWithClosure()
{
$im = new InstanceManager();
$obj1 = new TestAsset\BasicClass();
$im->addSharedInstanceWithParameters($obj1, 'foo', ['foo' => [function () {}]]);
$this->assertSame($obj1, $im->getSharedInstanceWithParameters('foo', ['foo' => [function () {}]]));
}
}
14 changes: 14 additions & 0 deletions test/TestAsset/ConstructorInjection/E.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Di\TestAsset\ConstructorInjection;

class E extends A
{
}
20 changes: 20 additions & 0 deletions test/TestAsset/ConstructorInjection/F.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Di\TestAsset\ConstructorInjection;

class F extends A
{
public $params;

public function __construct(array $params = [])
{
$this->params = $params;
}
}

0 comments on commit e8d4024

Please sign in to comment.