Skip to content

Commit

Permalink
Merge dcf9441 into 302191e
Browse files Browse the repository at this point in the history
  • Loading branch information
jflitton committed Jul 24, 2013
2 parents 302191e + dcf9441 commit 31baeef
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/DI/Container.php
Expand Up @@ -140,6 +140,23 @@ public function get($name, $useProxy = false)
throw new NotFoundException("No entry or class found for '$name'");
}

/**
* Performs injection on an existing instance
*
* @param object $instance Object to perform injection upon
* @throws InvalidArgumentException
* @throws DependencyException
* @return object $instance
*/
public function inject($instance)
{
$className = get_class($instance);
$definition = $this->definitionManager->getDefinition($className);

$instance = $this->factory->injectInstance($definition, $instance);
return $instance;
}

/**
* Define an object or a value in the container
*
Expand Down
28 changes: 28 additions & 0 deletions src/DI/Factory.php
Expand Up @@ -75,6 +75,34 @@ public function createInstance(ClassDefinition $classDefinition)
return $instance;
}

/**
* {@inheritdoc}
* @throws DependencyException
* @throws \DI\Definition\Exception\DefinitionException
*/
public function injectInstance(ClassDefinition $classDefinition, $instance)
{
try {
// Property injections
foreach ($classDefinition->getPropertyInjections() as $propertyInjection) {
$this->injectProperty($instance, $propertyInjection);
}

// Method injections
foreach ($classDefinition->getMethodInjections() as $methodInjection) {
$this->injectMethod($instance, $methodInjection);
}
} catch (DependencyException $e) {
throw $e;
} catch (DefinitionException $e) {
throw $e;
} catch (NotFoundException $e) {
throw new DependencyException("Error while injecting dependencies into " . $classDefinition->getClassName() . ": " . $e->getMessage(), 0, $e);
}

return $instance;
}

/**
* Creates an instance and inject dependencies through the constructor
*
Expand Down
2 changes: 1 addition & 1 deletion src/DI/FactoryInterface.php
Expand Up @@ -27,5 +27,5 @@ interface FactoryInterface
* @return object The instance
*/
function createInstance(ClassDefinition $classDefinition);

function injectInstance(ClassDefinition $classDefinition, $instance);
}
56 changes: 56 additions & 0 deletions tests/IntegrationTests/DI/InjectionTest.php
Expand Up @@ -14,6 +14,8 @@
use DI\Scope;
use DI\Container;
use IntegrationTests\DI\Fixtures\Class1;
use IntegrationTests\DI\Fixtures\Class2;
use IntegrationTests\DI\Fixtures\Implementation1;
use IntegrationTests\DI\Fixtures\LazyDependency;

/**
Expand Down Expand Up @@ -167,6 +169,33 @@ public function testPropertyInjection($type, Container $container)
$this->assertTrue($proxy->isProxyInitialized());
}

/**
* @dataProvider containerProvider
*/
public function testPropertyInjectionExistingObject($type, Container $container)
{
// Only constructor injection with reflection
if ($type == self::DEFINITION_REFLECTION) {
return;
}
/** @var $class1 Class1 */
$class1 = new Class1(new Class2(), new Implementation1());
$container->inject($class1);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\Class2', $class1->property1);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\Implementation1', $class1->property2);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\Class2', $class1->property3);
$this->assertEquals('bar', $class1->property4);
// Lazy injection
/** @var LazyDependency|\ProxyManager\Proxy\LazyLoadingInterface $proxy */
$proxy = $class1->property5;
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\LazyDependency', $proxy);
$this->assertInstanceOf('ProxyManager\Proxy\LazyLoadingInterface', $proxy);
$this->assertFalse($proxy->isProxyInitialized());
// Correct proxy resolution
$this->assertTrue($proxy->getValue());
$this->assertTrue($proxy->isProxyInitialized());
}

/**
* @dataProvider containerProvider
*/
Expand All @@ -193,6 +222,33 @@ public function testMethodInjection($type, Container $container)
$this->assertTrue($proxy->isProxyInitialized());
}

/**
* @dataProvider containerProvider
*/
public function testMethodInjectionExistingObject($type, Container $container)
{
// Only constructor injection with reflection
if ($type == self::DEFINITION_REFLECTION) {
return;
}
/** @var $class1 Class1 */
$class1 = new Class1(new Class2(), new Implementation1());
$container->inject($class1);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\Class2', $class1->method1Param1);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\Implementation1', $class1->method2Param1);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\Class2', $class1->method3Param1);
$this->assertEquals('bar', $class1->method3Param2);
$this->assertInstanceOf('IntegrationTests\DI\Fixtures\LazyDependency', $class1->method4Param1);
$this->assertInstanceOf('ProxyManager\Proxy\LazyLoadingInterface', $class1->method4Param1);
// Lazy injection
/** @var LazyDependency|\ProxyManager\Proxy\LazyLoadingInterface $proxy */
$proxy = $class1->method4Param1;
$this->assertFalse($proxy->isProxyInitialized());
// Correct proxy resolution
$this->assertTrue($proxy->getValue());
$this->assertTrue($proxy->isProxyInitialized());
}

/**
* @dataProvider containerProvider
*/
Expand Down
23 changes: 23 additions & 0 deletions tests/UnitTests/DI/ContainerTest.php
Expand Up @@ -152,6 +152,29 @@ public function testGetNonStringParameter()
$container->get(new stdClass());
}

/**
* Test that injecting an existing object returns the same reference to that object
*/
public function testInjectMaintainsReferentialEquality()
{
$container = new Container();
$instance = new stdClass();
$result = $container->inject($instance);

$this->assertSame($instance, $result);
}

/**
* Test that injection on null yields null
*/
public function testInjectNull()
{
$container = new Container();
$result = $container->inject(null);

$this->assertEquals($result, null);
}

/**
* We should be able to set a null value
* @see https://github.com/mnapoli/PHP-DI/issues/79
Expand Down

0 comments on commit 31baeef

Please sign in to comment.