The property injection in the ObjectContainer always
did reflect the object and made the property accessible,
even if the property was public and therefore accessible
by default.
With this patch, reflection is avoided for public
properties which increases the performance of public
property injection a lot.
Releases: master, 8.7
Resolves: #83155
Change-Id: I32f7c8e257f65da4a2fce1d7ee515d7954564387
Reviewed-on: https://review.typo3.org/54850
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Claus Due <claus@phpmind.net>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
if ($classSchema->isSingleton() && !$instanceToInject instanceof \TYPO3\CMS\Core\SingletonInterface) {
$this->getLogger()->notice('The singleton "' . $classSchema->getClassName() . '" needs a prototype in "' . $injectPropertyName . '". This is often a bad code smell; often you rather want to inject a singleton.');
}
if ($classSchema->isSingleton() && !$instanceToInject instanceof \TYPO3\CMS\Core\SingletonInterface) {
$this->getLogger()->notice('The singleton "' . $classSchema->getClassName() . '" needs a prototype in "' . $injectPropertyName . '". This is often a bad code smell; often you rather want to inject a singleton.');
}
- $propertyReflection = new \ReflectionProperty($instance, $injectPropertyName);
- $propertyReflection->setAccessible(true);
- $propertyReflection->setValue($instance, $instanceToInject);
+ if ($classSchema->getProperty($injectPropertyName)['public']) {
+ $instance->{$injectPropertyName} = $instanceToInject;
+ } else {
+ $propertyReflection = new \ReflectionProperty($instance, $injectPropertyName);
+ $propertyReflection->setAccessible(true);
+ $propertyReflection->setValue($instance, $instanceToInject);
+ }
*/
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Log\Logger;
*/
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Log\Logger;
+use TYPO3\CMS\Extbase\Object\Container\Container;
use TYPO3\CMS\Extbase\Object\Exception;
use TYPO3\CMS\Extbase\Object\Exception\CannotBuildObjectException;
use TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException;
use TYPO3\CMS\Extbase\Object\Exception;
use TYPO3\CMS\Extbase\Object\Exception\CannotBuildObjectException;
use TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException;
+use TYPO3\CMS\Extbase\Tests\Unit\Object\Container\Fixtures\ArgumentTestClassForPublicPropertyInjection;
+use TYPO3\CMS\Extbase\Tests\Unit\Object\Container\Fixtures\ProtectedPropertyInjectClass;
+use TYPO3\CMS\Extbase\Tests\Unit\Object\Container\Fixtures\PublicPropertyInjectClass;
$object->argumentTestClassTwo
);
}
$object->argumentTestClassTwo
);
}
+
+ /**
+ * @test
+ */
+ public function getInstanceInjectsPublicProperties()
+ {
+ $container = new Container();
+ $object = $container->getInstance(PublicPropertyInjectClass::class);
+ self::assertInstanceOf(ArgumentTestClassForPublicPropertyInjection::class, $object->foo);
+ }
+
+ /**
+ * @test
+ */
+ public function getInstanceInjectsProtectedProperties()
+ {
+ $container = new Container();
+ $object = $container->getInstance(ProtectedPropertyInjectClass::class);
+ self::assertInstanceOf(ArgumentTestClassForPublicPropertyInjection::class, $object->getFoo());
+ }
--- /dev/null
+<?php
+declare(strict_types=1);
+
+namespace TYPO3\CMS\Extbase\Tests\Unit\Object\Container\Fixtures;
+
+use TYPO3\CMS\Extbase\Annotation\Inject;
+
+class PublicPropertyInjectClass
+{
+ /**
+ * @Inject
+ * @var \TYPO3\CMS\Extbase\Tests\Unit\Object\Container\Fixtures\ArgumentTestClassForPublicPropertyInjection
+ */
+ public $foo;
+}
+
+class ArgumentTestClassForPublicPropertyInjection
+{
+}
+
+class ProtectedPropertyInjectClass
+{
+
+ /**
+ * @Inject
+ * @var \TYPO3\CMS\Extbase\Tests\Unit\Object\Container\Fixtures\ArgumentTestClassForPublicPropertyInjection
+ */
+ protected $foo;
+
+ public function getFoo()
+ {
+ return $this->foo;
+ }
+}