Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@
},
"require-dev": {
"maglnet/composer-require-checker": "^4.2",
"ocramius/proxy-manager": "^2.13",
"phpunit/phpunit": "^9.5",
"rector/rector": "^0.14.3",
"roave/infection-static-analysis-plugin": "^1.16",
"spatie/phpunit-watcher": "^1.23",
"vimeo/psalm": "^4.18",
"yiisoft/test-support": "^1.3"
},
"suggest": {
"ocramius/proxy-manager": "Install this package if you want to use lazy loading."
},
"autoload": {
"psr-4": {
"Yiisoft\\Factory\\": "src"
Expand Down
26 changes: 26 additions & 0 deletions src/Definition/Decorator/LazyDefinitionDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Factory\Definition\Decorator;

use ProxyManager\Factory\LazyLoadingValueHolderFactory;
use Psr\Container\ContainerInterface;
use Yiisoft\Definitions\Contract\DefinitionInterface;

final class LazyDefinitionDecorator implements DefinitionInterface
{
public function __construct(private LazyLoadingValueHolderFactory $factory, private DefinitionInterface $definition, private string $objectClass)
{
}

public function resolve(ContainerInterface $container): mixed
{
return $this->factory->createProxy(
$this->objectClass,
function (&$wrappedObject) use ($container) {
$wrappedObject = $this->definition->resolve($container);
}
);
}
}
20 changes: 20 additions & 0 deletions tests/Support/NotFinalClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Factory\Tests\Support;

class NotFinalClass
{
private $arguments;

public function __construct(...$arguments)
{
$this->arguments = $arguments;
}

public function getArguments(): array
{
return $this->arguments;
}
}
69 changes: 69 additions & 0 deletions tests/Unit/Definition/Decorator/LazyDefinitionDecoratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Factory\Tests\Unit\Definition;

use PHPUnit\Framework\TestCase;
use ProxyManager\Exception\InvalidProxiedClassException;
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
use ProxyManager\Proxy\LazyLoadingInterface;
use Yiisoft\Definitions\ArrayDefinition;
use Yiisoft\Factory\Definition\Decorator\LazyDefinitionDecorator;
use Yiisoft\Factory\Tests\Support\EngineInterface;
use Yiisoft\Factory\Tests\Support\NotFinalClass;
use Yiisoft\Factory\Tests\Support\Phone;
use Yiisoft\Test\Support\Container\SimpleContainer;

final class LazyDefinitionDecoratorTest extends TestCase
{
public function testDecorateFinalClass(): void
{
$container = new SimpleContainer();
$factory = new LazyLoadingValueHolderFactory();

$class = Phone::class;

$definition = ArrayDefinition::fromConfig([
ArrayDefinition::CLASS_NAME => $class,
]);
$definition = new LazyDefinitionDecorator($factory, $definition, $class);

$this->expectException(InvalidProxiedClassException::class);
$definition->resolve($container);
}

public function testDecorateNotFinalClass(): void
{
$container = new SimpleContainer();
$factory = new LazyLoadingValueHolderFactory();

$class = NotFinalClass::class;

$definition = ArrayDefinition::fromConfig([
ArrayDefinition::CLASS_NAME => $class,
]);
$definition = new LazyDefinitionDecorator($factory, $definition, $class);

$phone = $definition->resolve($container);

self::assertInstanceOf(LazyLoadingInterface::class, $phone);
}

public function testDecorateInterface(): void
{
$container = new SimpleContainer();
$factory = new LazyLoadingValueHolderFactory();

$class = EngineInterface::class;

$definition = ArrayDefinition::fromConfig([
ArrayDefinition::CLASS_NAME => $class,
]);
$definition = new LazyDefinitionDecorator($factory, $definition, $class);

$phone = $definition->resolve($container);

self::assertInstanceOf(LazyLoadingInterface::class, $phone);
}
}