Skip to content

Commit f5c2fd7

Browse files
committed
Activator uses abstract or interface type instances from container
1 parent faa75b1 commit f5c2fd7

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/Activator.php

+12-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ public function instantiate(string $type): object
3535
{
3636
return $this->track($type, function () use ($type) {
3737
$reflection = new ReflectionClass($type);
38+
39+
if ($reflection->isInterface() or $reflection->isAbstract()) {
40+
if ($this->container->has($type)) {
41+
return $this->container->get($type);
42+
}
43+
44+
throw new ContainerException('Type [' . $type . '] is not instantiable.');
45+
}
46+
3847
return ($constructor = $reflection->getConstructor())
3948
? $reflection->newInstanceArgs($this->getArguments($constructor))
4049
: $reflection->newInstance();
@@ -67,7 +76,7 @@ private static function getCallableReflectionFunctionAbstract(callable $callable
6776
return new ReflectionFunction($callable);
6877
}
6978

70-
throw new ContainerException('ReflectionFunctionAbstract for given callable type not implemented');
79+
throw new ContainerException('ReflectionFunctionAbstract for given callable type not implemented.');
7180
}
7281

7382
private static function getFunctionIdentifier(ReflectionFunctionAbstract $reflection): string
@@ -82,7 +91,7 @@ private static function getFunctionIdentifier(ReflectionFunctionAbstract $reflec
8291
return $reflection->getDeclaringClass()->getName() . '::' . $reflection->getName();
8392
}
8493

85-
throw new ContainerException('Function identifier not implemented for reflection of type ' . get_class($reflection));
94+
throw new ContainerException('Function identifier not implemented for reflection of type ' . get_class($reflection) . '.');
8695
}
8796

8897
private function getArguments(ReflectionFunctionAbstract $reflection): array
@@ -115,6 +124,6 @@ private function getArgument(ReflectionParameter $parameter)
115124
return $this->instantiate($typeName);
116125
}
117126

118-
throw new ContainerException('Cannot resolve value for parameter ' . $parameter->getName());
127+
throw new ContainerException('Cannot resolve value for parameter [' . $parameter->getName() . '] with type [' . $typeName . '].');
119128
}
120129
}

tests/ActivatorTest.php

+26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use Featherbits\ServiceContainer\Container;
55
use Featherbits\ServiceContainer\InstanceGetterStrategies\ByFactory;
66
use Featherbits\ServiceContainer\Activator;
7+
use Featherbits\ServiceContainer\InstanceGetterStrategies\ByType;
78

89
class ClassWithTestInterfaceParameter
910
{
@@ -15,6 +16,16 @@ public function __construct(TestInterface $instance)
1516
}
1617
}
1718

19+
class ClassWithTestClassParameter
20+
{
21+
public ?TestClass $instance = null;
22+
23+
public function __construct(TestClass $instance)
24+
{
25+
$this->instance = $instance;
26+
}
27+
}
28+
1829
final class ActivatorTest extends TestCase
1930
{
2031
public function testCallCallableWithResolvedParameterFromContainer()
@@ -46,4 +57,19 @@ public function testInstantiateClassWithResolvedParameterFromContainer()
4657

4758
$this->assertSame($instance, $instance2);
4859
}
60+
61+
public function testInjectClassInstanceAsDependency()
62+
{
63+
$activator = new Activator(new Container());
64+
$instance = $activator->instantiate(ClassWithTestClassParameter::class)->instance;
65+
$this->assertInstanceOf(TestClass::class, $instance);
66+
}
67+
68+
public function testInstantiateInterfaceWhenImplementationAddedToContainer()
69+
{
70+
$container = new Container();
71+
$container->set(TestInterface::class, new ByType(TestClass::class));
72+
$activator = new Activator($container);
73+
$this->assertInstanceOf(TestInterface::class, $activator->instantiate(TestInterface::class));
74+
}
4975
}

0 commit comments

Comments
 (0)