Skip to content

Commit dd6b43f

Browse files
committed
Add object by class from container in MethodFactory
1 parent 3eaf84b commit dd6b43f

File tree

2 files changed

+59
-32
lines changed

2 files changed

+59
-32
lines changed

src/Factory/MethodFactory.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ public function __invoke(ContainerInterface $container): mixed
8484
return $reflectionMethod->invokeArgs(null, $arguments);
8585
}
8686

87-
return $reflectionMethod->invokeArgs(new ($this->class)(), $arguments);
87+
try {
88+
$object = $container->get($this->class);
89+
} catch (\Throwable) {
90+
$object = new ($this->class)();
91+
}
92+
93+
return $reflectionMethod->invokeArgs($object, $arguments);
8894
}
8995
}

tests/Factory/MethodFactoryTest.php

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,6 @@
22

33
declare(strict_types=1);
44

5-
/**
6-
* This file is part of php-fast-forward/container.
7-
*
8-
* This source file is subject to the license bundled
9-
* with this source code in the file LICENSE.
10-
*
11-
* @link https://github.com/php-fast-forward/container
12-
* @copyright Copyright (c) 2025 Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
13-
* @license https://opensource.org/licenses/MIT MIT License
14-
*/
15-
165
namespace FastForward\Container\Tests\Factory;
176

187
use FastForward\Container\Exception\RuntimeException;
@@ -23,9 +12,6 @@
2312
use Prophecy\PhpUnit\ProphecyTrait;
2413
use Psr\Container\ContainerInterface;
2514

26-
/**
27-
* @internal
28-
*/
2915
#[CoversClass(MethodFactory::class)]
3016
#[UsesClass(RuntimeException::class)]
3117
final class MethodFactoryTest extends TestCase
@@ -34,14 +20,14 @@ final class MethodFactoryTest extends TestCase
3420

3521
public function testInvokeInstanceMethod(): void
3622
{
37-
$service = new MethodTarget();
23+
$service = new MethodFactoryTestTargetStub();
3824

3925
$container = $this->prophesize(ContainerInterface::class);
4026
$container->has('prefix')->willReturn(false);
41-
$container->has(MethodTarget::class)->willReturn(true);
42-
$container->get(MethodTarget::class)->willReturn($service);
27+
$container->has(MethodFactoryTestTargetStub::class)->willReturn(true);
28+
$container->get(MethodFactoryTestTargetStub::class)->willReturn($service);
4329

44-
$factory = new MethodFactory(MethodTarget::class, 'instanceMethod', 'prefix');
30+
$factory = new MethodFactory(MethodFactoryTestTargetStub::class, 'instanceMethod', 'prefix');
4531

4632
$result = $factory($container->reveal());
4733

@@ -51,10 +37,9 @@ public function testInvokeInstanceMethod(): void
5137
public function testInvokeStaticMethod(): void
5238
{
5339
$container = $this->prophesize(ContainerInterface::class);
54-
$container->has(MethodTarget::class)->willReturn(false);
5540
$container->has('value')->willReturn(false);
5641

57-
$factory = new MethodFactory(MethodTarget::class, 'staticMethod', 'value');
42+
$factory = new MethodFactory(MethodFactoryTestTargetStub::class, 'staticMethod', 'value');
5843

5944
$result = $factory($container->reveal());
6045

@@ -63,16 +48,16 @@ public function testInvokeStaticMethod(): void
6348

6449
public function testInvokeResolvesArgumentsFromContainer(): void
6550
{
66-
$service = new MethodTarget();
51+
$service = new MethodFactoryTestTargetStub();
6752
$argObj = new \stdClass();
6853

6954
$container = $this->prophesize(ContainerInterface::class);
70-
$container->has(MethodTarget::class)->willReturn(true);
71-
$container->get(MethodTarget::class)->willReturn($service);
55+
$container->has(MethodFactoryTestTargetStub::class)->willReturn(true);
56+
$container->get(MethodFactoryTestTargetStub::class)->willReturn($service);
7257
$container->has('dependency')->willReturn(true);
7358
$container->get('dependency')->willReturn($argObj);
7459

75-
$factory = new MethodFactory(MethodTarget::class, 'acceptsObject', 'dependency');
60+
$factory = new MethodFactory(MethodFactoryTestTargetStub::class, 'acceptsObject', 'dependency');
7661

7762
$result = $factory($container->reveal());
7863

@@ -81,23 +66,50 @@ public function testInvokeResolvesArgumentsFromContainer(): void
8166

8267
public function testInvokeThrowsForNonPublicMethod(): void
8368
{
84-
$service = new MethodTarget();
85-
8669
$container = $this->prophesize(ContainerInterface::class);
87-
$container->has(MethodTarget::class)->willReturn(true);
88-
$container->get(MethodTarget::class)->willReturn($service);
70+
$container->has(MethodFactoryTestTargetStub::class)->willReturn(false);
8971

90-
$factory = new MethodFactory(MethodTarget::class, 'privateMethod');
72+
$factory = new MethodFactory(MethodFactoryTestTargetStub::class, 'privateMethod');
9173

9274
$this->expectException(RuntimeException::class);
93-
$this->expectExceptionMessage('Method "FastForward\Container\Tests\Factory\MethodTarget::privateMethod" MUST be public to be invoked as a service.');
9475

9576
$factory($container->reveal());
9677
}
78+
79+
public function testInvokeWillConstructTargetIfContainerDoesNotProvide(): void
80+
{
81+
$container = $this->prophesize(ContainerInterface::class);
82+
$container->has('prefix')->willReturn(false);
83+
$container->get(MethodFactoryTestTargetStub::class)->willThrow(new \Exception());
84+
85+
$factory = new MethodFactory(MethodFactoryTestTargetStub::class, 'instanceMethod', 'prefix');
86+
87+
$result = $factory($container->reveal());
88+
89+
self::assertSame('prefix-instance', $result);
90+
}
91+
92+
public function testConstructorDependencyIsResolvedFromContainer(): void
93+
{
94+
$dependency = new MethodFactoryTestDependencyStub();
95+
96+
$container = $this->prophesize(ContainerInterface::class);
97+
$container->has(MethodFactoryTestTargetStub::class)->willReturn(true);
98+
$container->get(MethodFactoryTestTargetStub::class)->willReturn(new MethodFactoryTestTargetStub($dependency))->shouldBeCalledOnce();
99+
$container->has('suffix')->willReturn(false);
100+
101+
$factory = new MethodFactory(MethodFactoryTestTargetStub::class, 'usesConstructorArgument', 'suffix');
102+
103+
$result = $factory($container->reveal());
104+
105+
self::assertSame(MethodFactoryTestDependencyStub::class . '-suffix', $result);
106+
}
97107
}
98108

99-
class MethodTarget
109+
class MethodFactoryTestTargetStub
100110
{
111+
public function __construct(private ?MethodFactoryTestDependencyStub $dependency = null) {}
112+
101113
public function instanceMethod(string $prefix): string
102114
{
103115
return $prefix . '-instance';
@@ -113,5 +125,14 @@ public function acceptsObject(object $obj): object
113125
return $obj;
114126
}
115127

128+
public function usesConstructorArgument(string $suffix): string
129+
{
130+
return $this->dependency::class . '-' . $suffix;
131+
}
132+
116133
private function privateMethod(): void {}
117134
}
135+
136+
class MethodFactoryTestDependencyStub
137+
{
138+
}

0 commit comments

Comments
 (0)