diff --git a/composer.json b/composer.json index 650814de..3e11d45b 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ }, "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", @@ -29,6 +30,9 @@ "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" diff --git a/src/Definition/Decorator/LazyDefinitionDecorator.php b/src/Definition/Decorator/LazyDefinitionDecorator.php new file mode 100644 index 00000000..e7a010b8 --- /dev/null +++ b/src/Definition/Decorator/LazyDefinitionDecorator.php @@ -0,0 +1,26 @@ +factory->createProxy( + $this->objectClass, + function (&$wrappedObject) use ($container) { + $wrappedObject = $this->definition->resolve($container); + } + ); + } +} diff --git a/tests/Support/NotFinalClass.php b/tests/Support/NotFinalClass.php new file mode 100644 index 00000000..bd0a3071 --- /dev/null +++ b/tests/Support/NotFinalClass.php @@ -0,0 +1,20 @@ +arguments = $arguments; + } + + public function getArguments(): array + { + return $this->arguments; + } +} diff --git a/tests/Unit/Definition/Decorator/LazyDefinitionDecoratorTest.php b/tests/Unit/Definition/Decorator/LazyDefinitionDecoratorTest.php new file mode 100644 index 00000000..76580ff6 --- /dev/null +++ b/tests/Unit/Definition/Decorator/LazyDefinitionDecoratorTest.php @@ -0,0 +1,69 @@ + $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); + } +}