Skip to content

Commit

Permalink
Automatic class resolution w/o rule
Browse files Browse the repository at this point in the history
  • Loading branch information
rwstream9 committed May 11, 2020
1 parent 1579b06 commit ffae951
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 8 deletions.
3 changes: 3 additions & 0 deletions composer.json
Expand Up @@ -20,5 +20,8 @@
"LiftKit\\Tests\\Unit\\DependencyInjection\\": "tests/unit/",
"LiftKit\\Tests\\Mock\\DependencyInjection\\": "tests/mock/"
}
},
"require": {
"psr/container": "^1.0"
}
}
58 changes: 55 additions & 3 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/ClassIndex/ClassIndex.php
Expand Up @@ -97,7 +97,11 @@ public function resolveClassToRule ($className)

$className = $this->resolveAliasToClass($className);

return $this->classToRuleIndex[$className];
if (isset($this->classToRuleIndex[$className])) {
return $this->classToRuleIndex[$className];
} else {
return null;
}
}


Expand Down
53 changes: 49 additions & 4 deletions src/Container/Container.php
Expand Up @@ -12,14 +12,15 @@
use LiftKit\DependencyInjection\Rule\SingletonCallbackRule;
use LiftKit\DependencyInjection\Rule\StoredObjectRule;
use LiftKit\DependencyInjection\ClassIndex\ClassIndex;
use Psr\Container\ContainerInterface;


/**
* Class Base
*
* @package LiftKit\DependencyInjection\Container
*/
class Container
class Container implements ContainerInterface
{
/**
* @var Rule[]
Expand Down Expand Up @@ -147,16 +148,54 @@ public function storeObject ($identifier, $object)
*/
public function getObject ($identifier, array $parameters = array())
{
if (! isset($this->rules[$identifier])) {
throw new DependencyException('Unknown object or rule ' . var_export($identifier, true) . '.');
if (isset($this->rules[$identifier])) {
$rule = $this->rules[$identifier];

} else if (class_exists($identifier)) {
if ($this->classIndex->resolveClassToRule($identifier)) {
$identifier = $this->classIndex->resolveClassToRule($identifier);
$rule = $this->rules[$identifier];

} else {
if (! count($parameters)) {
$rule = new SingletonClassBindingRule(
$this,
$this->classIndex,
$identifier
);

} else {
$rule = new ClassBindingRule(
$this,
$this->classIndex,
$identifier
);
}

$this->rules[$identifier] = $rule;
}

} else {
throw new DependencyException('Unknown class, object or rule ' . var_export($identifier, true) . '.');
}

$rule = $this->rules[$identifier];

return $rule->resolve($parameters);
}


public function get ($identifier)
{
return $this->getObject($identifier);
}


public function has ($identifier)
{
return isset($this->rules[$identifier]);
}


/**
* @param $identifier
* @param $className
Expand Down Expand Up @@ -219,4 +258,10 @@ public function bindClassToAlias ($className, $resolvedClassName)

return $this;
}


public function registerClass ($className)
{
$this->bindRuleToClass($className, $className);
}
}
30 changes: 30 additions & 0 deletions tests/mock/ClassG.php
@@ -0,0 +1,30 @@
<?php


namespace LiftKit\Tests\Mock\DependencyInjection;


class ClassG
{
protected $a;
protected $param;


public function __construct (ClassA $a, $param = true)
{
$this->a = $a;
$this->param = $param;
}


public function getA ()
{
return $this->a;
}


public function getParam ()
{
return $this->param;
}
}
97 changes: 97 additions & 0 deletions tests/unit/Container/ContainerTest.php
Expand Up @@ -12,6 +12,7 @@
use LiftKit\Tests\Mock\DependencyInjection\ClassD;
use LiftKit\Tests\Mock\DependencyInjection\ClassE;
use LiftKit\Tests\Mock\DependencyInjection\ClassF;
use LiftKit\Tests\Mock\DependencyInjection\ClassG;


class ContainerTest extends PHPUnit_Framework_TestCase
Expand Down Expand Up @@ -314,4 +315,100 @@ public function testWithOptionalParams ()
$this->assertSame(ClassA::class, get_class($object->getA()));
$this->assertEquals(false, $object->getParam());
}


public function testGetClassWithNoRule ()
{
$g = $this->container->getObject(ClassG::class);

$this->assertEquals(ClassG::class, get_class($g));

$a = $g->getA();

$this->assertEquals(ClassA::class, get_class($a));
}


public function testGetClassWithNoRuleWithMultipleParameters ()
{
$object = $this->container->getObject(ClassE::class, [new ClassA, new ClassB]);

$this->assertSame(ClassA::class, get_class($object->getA()));
$this->assertSame(ClassB::class, get_class($object->getB()));
}


public function testGetAliasClassWithNoRule ()
{
$this->container->bindClassToAlias(ClassA::class, ClassB::class);

$object = $this->container->getObject(ClassA::class);

$this->assertEquals(ClassB::class, get_class($object));
}


public function testBindClassToRule ()
{
$b = new ClassB;

$this->container->setRule('A', function () use ($b) {
return $b;
});

$this->container->bindClassToRule(ClassA::class, 'A');

$object1 = $this->container->getObject('A');
$object2 = $this->container->getObject(ClassA::class);

$this->assertSame($b, $object1);
$this->assertSame($b, $object2);
}


public function testGetClassWithNoRuleSingleton ()
{
$a1 = $this->container->getObject(ClassA::class);
$a2 = $this->container->getObject(ClassA::class);

$this->assertSame($a1, $a2);

$e1 = $this->container->getObject(ClassE::class, [new ClassA, new ClassB]);
$e2 = $this->container->getObject(ClassE::class, [new ClassA, new ClassB]);

$this->assertNotSame($e1, $e2);
}


public function testGet ()
{
$a1 = $this->container->getObject(ClassA::class);
$a2 = $this->container->get(ClassA::class);

$this->assertSame($a1, $a2);
}


public function testRegisterClass ()
{
$this->container->registerClass(ClassA::class);

$a = $this->container->get(ClassA::class);

$this->assertInstanceOf(ClassA::class, $a);
}


public function testHas ()
{
$this->assertFalse(
$this->container->has(ClassA::class)
);

$this->container->registerClass(ClassA::class);

$this->assertTrue(
$this->container->has(ClassA::class)
);
}
}

0 comments on commit ffae951

Please sign in to comment.