Skip to content

Commit ead3826

Browse files
FedikHLeithner
andauthored
Lazy Objects helper (#64)
* lazy helper * compatibility check * comments * fixes * without tagging * test * test * only proxy * lazy variants * lazy variants * lazy variants * Update src/Container.php Co-authored-by: Harald Leithner <leithner@itronic.at> * lazy variants * lazy variants final * lazy variants final * lazy variants test --------- Co-authored-by: Harald Leithner <leithner@itronic.at>
1 parent 1ca6ddd commit ead3826

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

Tests/ContainerSetupTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,46 @@ static function () {
318318

319319
$container->get('foo');
320320
}
321+
322+
/**
323+
* @testdox Create Lazy Proxy
324+
*
325+
* @covers Joomla\DI\Container
326+
*/
327+
public function testCreateLazyProxy()
328+
{
329+
$container = new Container();
330+
$container->lazy(Stub6::class, function () {
331+
return new Stub6();
332+
});
333+
334+
$resource = $container->get(Stub6::class);
335+
336+
$this->assertTrue($resource instanceof Stub6);
337+
}
338+
339+
/**
340+
* @testdox If the resource is created with a proxy class
341+
*
342+
* @uses Joomla\DI\Container
343+
*/
344+
public function testGetLazyProxyInstance()
345+
{
346+
if (PHP_VERSION_ID < 80400) {
347+
$this->markTestSkipped('Lazy objects are only supported in PHP 8.4 or newer.');
348+
}
349+
350+
$factoryCalled = false;
351+
352+
$container = new Container();
353+
$container->lazy(Stub6::class, function () use (&$factoryCalled) {
354+
$factoryCalled = true;
355+
return new Stub6();
356+
});
357+
358+
$resource = $container->get(Stub6::class);
359+
360+
$this->assertTrue((new \ReflectionClass(Stub6::class))->isUninitializedLazyObject($resource));
361+
$this->assertFalse($factoryCalled);
362+
}
321363
}

src/Container.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,34 @@ public function share($key, $value, $protected = false)
665665
return $this->set($key, $value, true, $protected);
666666
}
667667

668+
/**
669+
* Create a lazy proxy resource for given class, and register it in the Container.
670+
*
671+
* @param string $class Full class name of the resource.
672+
* @param callable $factory Callback to create the class instance. The callback must return instance of the given class.
673+
* @param boolean $shared True to create and store a shared instance.
674+
* @param boolean $protected True to protect this item from being overwritten. Useful for services.
675+
*
676+
* @return $this
677+
*
678+
* @since __DEPLOY_VERSION__
679+
*/
680+
final public function lazy(string $class, callable $factory, bool $shared = false, bool $protected = false): static
681+
{
682+
if (PHP_VERSION_ID < 80400) {
683+
return $this->set($class, $factory, $shared, $protected);
684+
}
685+
686+
// Create a Lazy Proxy factory
687+
$lazyFactory = function () use ($class, $factory) {
688+
return (new \ReflectionClass($class))->newLazyProxy(function () use ($factory) {
689+
return $factory($this);
690+
});
691+
};
692+
693+
return $this->set($class, $lazyFactory, $shared, $protected);
694+
}
695+
668696
/**
669697
* Get the raw data assigned to a key.
670698
*

0 commit comments

Comments
 (0)