From c3891b0b7e0d6c06e12417cd28911c02c28790dc Mon Sep 17 00:00:00 2001 From: Matthieu Napoli Date: Sat, 9 Apr 2022 20:26:45 +0200 Subject: [PATCH] Drop support for `@Inject` annotations in favor of attributes --- .php-cs-fixer.php | 3 +- composer.json | 2 - couscous.yml | 2 +- doc/README.md | 2 +- doc/annotations.md | 146 +--------- doc/container-configuration.md | 4 +- doc/container.md | 6 +- doc/definition-overriding.md | 16 +- doc/definition.md | 8 +- doc/frameworks/silex.md | 2 +- doc/frameworks/slim.md | 2 +- doc/frameworks/symfony2.md | 12 +- doc/frameworks/zf1.md | 6 +- doc/frameworks/zf2.md | 18 +- doc/getting-started.md | 4 +- doc/lazy-injection.md | 8 +- doc/migration/7.0.md | 30 +- doc/performances.md | 8 +- doc/php-definitions.md | 2 +- src/Annotation/Inject.php | 91 ------ src/Annotation/Injectable.php | 38 --- src/Attribute/Inject.php | 8 +- src/Attribute/Injectable.php | 2 +- src/ContainerBuilder.php | 26 +- ...lidAnnotation.php => InvalidAttribute.php} | 4 +- .../Helper/AutowireDefinitionHelper.php | 8 +- .../Helper/FactoryDefinitionHelper.php | 2 +- .../Source/AnnotationBasedAutowiring.php | 273 ------------------ .../Source/AttributeBasedAutowiring.php | 27 +- tests/IntegrationTest/Annotations/A.php | 9 - .../Annotations/AnnotationsTest.php | 105 ------- tests/IntegrationTest/Annotations/B.php | 35 --- tests/IntegrationTest/Annotations/C.php | 9 - tests/IntegrationTest/Annotations/Child.php | 20 -- tests/IntegrationTest/Annotations/D.php | 9 - .../Annotations/NamedInjection.php | 15 - .../CircularDependencyTest.php | 4 +- .../IntegrationTest/ContainerInjectOnTest.php | 21 +- tests/IntegrationTest/ContainerMakeTest.php | 2 +- .../Definitions/AnnotationTest.php | 189 ------------ .../ConstructorInjection.php | 6 +- .../AutowireDefinition/MethodInjection.php | 6 +- .../Definitions/AutowireDefinitionTest.php | 4 +- .../Definitions/WildcardDefinitionsTest.php | 8 +- .../IntegrationTest/ErrorMessages/Buggy2.php | 7 +- .../IntegrationTest/ErrorMessages/Buggy3.php | 6 +- .../IntegrationTest/ErrorMessages/Buggy4.php | 6 +- .../IntegrationTest/ErrorMessages/Buggy5.php | 6 +- .../ErrorMessages/ErrorMessagesTest.php | 10 +- tests/IntegrationTest/Fixtures/Class1.php | 41 +-- .../Fixtures/InheritanceTest/BaseClass.php | 10 +- .../Fixtures/InheritanceTest/SubClass.php | 6 +- tests/IntegrationTest/Fixtures/Interface1.php | 4 +- .../Fixtures/LazyDependency.php | 9 +- tests/IntegrationTest/InheritanceTest.php | 12 +- .../IntegrationTest/Issues/Issue72/Class1.php | 6 +- tests/IntegrationTest/Issues/Issue72Test.php | 10 +- tests/PerformanceTest/autowire.php | 2 +- tests/PerformanceTest/call.php | 2 +- tests/PerformanceTest/factory.php | 2 +- tests/PerformanceTest/get-cache.php | 2 +- tests/PerformanceTest/get-object.php | 2 +- tests/PerformanceTest/get.php | 2 +- .../Annotation/Fixtures/Dependency.php | 9 - .../Annotation/Fixtures/InjectFixture.php | 54 ---- .../Annotation/Fixtures/Injectable1.php | 12 - .../Annotation/Fixtures/Injectable2.php | 12 - .../Fixtures/MixedAnnotationsFixture.php | 17 -- .../Fixtures/NonImportedInjectFixture.php | 13 - tests/UnitTest/Annotation/InjectTest.php | 134 --------- tests/UnitTest/Annotation/InjectableTest.php | 52 ---- tests/UnitTest/Attributes/InjectTest.php | 4 +- tests/UnitTest/ContainerBuilderTest.php | 4 +- ...t.php => AttributeBasedAutowiringTest.php} | 78 +++-- .../Source/Fixtures/AnnotationFixture3.php | 6 +- .../Source/Fixtures/AnnotationFixture4.php | 6 +- .../Source/Fixtures/AnnotationFixture5.php | 6 +- .../Fixtures/AnnotationFixtureChild.php | 10 +- .../Fixtures/AnnotationFixtureParent.php | 14 +- .../AnnotationFixtureScalarTypedProperty.php | 6 +- .../AnnotationFixtureTypedProperties.php | 10 +- .../Fixtures/AnnotationInjectableFixture.php | 6 +- ...tationFixture.php => AttributeFixture.php} | 48 +-- .../Fixtures/Class1CircularDependencies.php | 6 +- .../Fixtures/Class2CircularDependencies.php | 7 +- tests/UnitTest/Fixtures/Singleton.php | 6 +- 86 files changed, 255 insertions(+), 1612 deletions(-) delete mode 100644 src/Annotation/Inject.php delete mode 100644 src/Annotation/Injectable.php rename src/Definition/Exception/{InvalidAnnotation.php => InvalidAttribute.php} (57%) delete mode 100644 src/Definition/Source/AnnotationBasedAutowiring.php delete mode 100644 tests/IntegrationTest/Annotations/A.php delete mode 100644 tests/IntegrationTest/Annotations/AnnotationsTest.php delete mode 100644 tests/IntegrationTest/Annotations/B.php delete mode 100644 tests/IntegrationTest/Annotations/C.php delete mode 100644 tests/IntegrationTest/Annotations/Child.php delete mode 100644 tests/IntegrationTest/Annotations/D.php delete mode 100644 tests/IntegrationTest/Annotations/NamedInjection.php delete mode 100644 tests/IntegrationTest/Definitions/AnnotationTest.php delete mode 100644 tests/UnitTest/Annotation/Fixtures/Dependency.php delete mode 100644 tests/UnitTest/Annotation/Fixtures/InjectFixture.php delete mode 100644 tests/UnitTest/Annotation/Fixtures/Injectable1.php delete mode 100644 tests/UnitTest/Annotation/Fixtures/Injectable2.php delete mode 100644 tests/UnitTest/Annotation/Fixtures/MixedAnnotationsFixture.php delete mode 100644 tests/UnitTest/Annotation/Fixtures/NonImportedInjectFixture.php delete mode 100644 tests/UnitTest/Annotation/InjectTest.php delete mode 100644 tests/UnitTest/Annotation/InjectableTest.php rename tests/UnitTest/Definition/Source/{AnnotationBasedAutowiringTest.php => AttributeBasedAutowiringTest.php} (72%) rename tests/UnitTest/Definition/Source/Fixtures/{AnnotationFixture.php => AttributeFixture.php} (67%) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index ba325f0b6..bdeaf4aca 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -31,7 +31,7 @@ 'no_useless_else' => true, 'no_useless_return' => true, 'ordered_imports' => true, - 'php_unit_strict' => true, + 'php_unit_strict' => false, 'phpdoc_add_missing_param_annotation' => false, 'phpdoc_align' => false, 'phpdoc_annotation_without_dot' => false, @@ -49,6 +49,7 @@ 'yoda_style' => false, 'native_function_invocation' => false, 'single_line_throw' => false, + 'php_unit_method_casing' => false, ]) ->setRiskyAllowed(true) ->setFinder($finder); diff --git a/composer.json b/composer.json index 4c5f82513..4e60d9874 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,6 @@ "require-dev": { "phpunit/phpunit": "^9.5", "mnapoli/phpunit-easymock": "^1.3", - "doctrine/annotations": "~1.10", "ocramius/proxy-manager": "^2.11.2", "friendsofphp/php-cs-fixer": "^3", "vimeo/psalm": "^4.6" @@ -41,7 +40,6 @@ "psr/container-implementation": "^1.0" }, "suggest": { - "doctrine/annotations": "Install it if you want to use annotations (version ^1.7)", "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ^2.3)" } } diff --git a/couscous.yml b/couscous.yml index a13ece865..68689f3b7 100644 --- a/couscous.yml +++ b/couscous.yml @@ -47,7 +47,7 @@ menu: text: PHP definitions url: doc/php-definitions.html attributes: - text: PHP 8 attributes + text: PHP attributes url: doc/attributes.html annotations: text: Annotations diff --git a/doc/README.md b/doc/README.md index 44abbdc75..cc9286a8c 100644 --- a/doc/README.md +++ b/doc/README.md @@ -19,7 +19,7 @@ title: Documentation index * [Introduction](definition.md) * [Autowiring](autowiring.md) * [PHP definitions](php-definitions.md) -* [Annotations](annotations.md) +* [Attributes](attributes.md) * [Definition extensions and overriding](definition-overriding.md) ### Frameworks integration diff --git a/doc/annotations.md b/doc/annotations.md index daa88824d..6744bd0a7 100644 --- a/doc/annotations.md +++ b/doc/annotations.md @@ -5,148 +5,4 @@ current_menu: annotations # Annotations -**Since PHP 8, annotations are deprecated in favor of [PHP attributes](attributes.md).** - ---- - -On top of [autowiring](autowiring.md) and [PHP configuration files](php-definitions.md), you can define injections using annotations. - -Using annotations do not affect performances when [compiling the container](performances.md). - -## Installation - -Annotations **are disabled by default**. To be able to use them, you first need to install the [Doctrine Annotations](http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html) library using Composer: - -``` -composer require doctrine/annotations -``` - -Then you need to [configure the `ContainerBuilder`](container-configuration.md) to use them: - -```php -$containerBuilder->useAnnotations(true); -``` - -Annotations are written in PHP docblock comments. They are used by a lot of modern libraries and frameworks, like [Doctrine](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/index.html), [Symfony](http://symfony.com/) and more. - -## @Inject - -`@Inject` lets you define where PHP-DI should inject something, and optionally what it should inject. - -It can be used on: - -- the constructor (constructor injection) -- methods (setter/method injection) -- properties (property injection) - -*Note: property injections occur after the constructor is executed, so any injectable property will be null inside `__construct`.* - -**Since PHP-DI 7, `@Inject` will ignore types declared in phpdoc. Only types specified in PHP code will be considered.** - -Here is an example of all possible uses of the `@Inject` annotation: - -```php -class Example -{ - /** - * Annotation combined with a type on the property: - * - * @Inject - */ - private Foo $property1; - - /** - * Explicit definition of the entry to inject: - * - * @Inject("db.host") - */ - private $property2; - - /** - * Annotation specifying exactly what to inject: - * - * @Inject({"db.host", "db.name"}) - */ - public function __construct($param1, $param2) - { - } - - /** - * Annotation combined with PHP types: - * - * @Inject - */ - public function method1(Foo $param) - { - } - - /** - * Explicit definition of the entries to inject: - * - * @Inject({"db.host", "db.name"}) - */ - public function method2($param1, $param2) - { - } - - /** - * Explicit definition of parameters by their name - * (types are used for the other parameters): - * - * @Inject({"param2" = "db.host"}) - */ - public function method3(Foo $param1, $param2) - { - } -} -``` - -*Note: importing annotations with `use DI\Annotation\Inject;` is optional.* - -### Troubleshooting @Inject - -- you must use double quotes (`"`) instead of single quotes(`'`), for example: `@Inject("foo")` -- what's inside `@Inject()` must be in quotes, even if it's a class name: `@Inject("Acme\Blog\ArticleRepository")` -- `@Inject` is not meant to be used on the method to call with [`Container::call()`](container.md#call) (it will be ignored) -- **Since PHP-DI 7, `@Inject` will ignore types declared in phpdoc. Only types specified in PHP code will be considered.** - -Note that `@Inject` is implicit on all constructors. - -## Injectable - -The `@Injectable` annotation lets you set options on injectable classes: - -```php -/** - * @Injectable(lazy=true) - */ -class Example -{ -} -``` - -**The `@Injectable` annotation is optional: by default, all classes are injectable.** - -## Limitations - -There are things that can't be defined with annotations: - -- values (instead of classes) -- mapping interfaces to implementations -- defining entries with an anonymous function - -For that, you can combine annotations with [definitions in PHP](php-definitions.md). - -## Troubleshooting - -Since annotations are in PHP docblocks, the opcache option `opcache.save_comments` must be set to `1`. If it is set to `0`, comments will be stripped from the source code and annotations will not work. - -The default value for this option is `1` so everything should work by default. - -To check the value of this option, you can run the following command: - -``` -$ php -i | grep "opcache.save_comments" -``` - -Furthermore, please mind that annotations are case-sensitive. You should write `@Inject` and `@Injectable` instead of `@inject` and `@injectable` to avoid bugs on certain systems. +**Since PHP-DI 7, annotations have been replaced by [PHP attributes](attributes.md).** diff --git a/doc/container-configuration.md b/doc/container-configuration.md index 5d0311eca..9470b57e6 100644 --- a/doc/container-configuration.md +++ b/doc/container-configuration.md @@ -13,7 +13,7 @@ PHP-DI's container is preconfigured for "plug and play". You can start using it $container = new Container(); ``` -By default, [Autowiring](definition.md) will be enabled. [Annotations](annotations.md) are disabled by default. +By default, [Autowiring](definition.md) will be enabled. [Attributes](attributes.md) are disabled by default. To register [definitions using an array](php-definitions.md): @@ -51,7 +51,7 @@ If you want to use PHP-DI's container as a simple container (no autowiring or an ```php $builder = new \DI\ContainerBuilder(); $builder->useAutowiring(false); -$builder->useAnnotations(false); +$builder->useAttributes(false); $container = $builder->build(); ``` diff --git a/doc/container.md b/doc/container.md index a08546545..a5921b173 100644 --- a/doc/container.md +++ b/doc/container.md @@ -188,9 +188,7 @@ Example: ```php class UserController extends BaseController { - /** - * @Inject - */ + #[Inject] private SomeService $someService; public function __construct() @@ -207,7 +205,7 @@ class UserController extends BaseController ``` As you might have guessed, you can't use constructor injection with this method. -But other kind of injections (property or setter) will work, whether you use annotations +But other kind of injections (property or setter) will work, whether you use attributes or whether you configured your object in a definition file. ## Extending the container diff --git a/doc/definition-overriding.md b/doc/definition-overriding.md index 37c4ae2e5..e576782e4 100644 --- a/doc/definition-overriding.md +++ b/doc/definition-overriding.md @@ -5,7 +5,7 @@ current_menu: definition-overriding # Definition extensions and overriding -A simple application usually takes advantage of one or two *definition sources*: autowiring (or annotations) + a definition file/array. +A simple application usually takes advantage of one or two *definition sources*: autowiring (with or without attributes) + a definition file/array. However in more complex applications or modular systems you might want to have multiple definition files (e.g. one per modules/bundles/plugins/…). In this case, PHP-DI provides a clear and powerful system to **override and/or extend definitions**. @@ -14,7 +14,7 @@ However in more complex applications or modular systems you might want to have m From the lowest priority to the highest: - autowiring if enabled -- annotations if enabled +- attributes if enabled - PHP definitions (file or array) in the order they were added - definitions added straight in the container with `$container->set()` @@ -29,21 +29,21 @@ class Foo } ``` -PHP-DI would inject an instance of `Bar` using autowiring. Annotations have a higher priority, we can use it to override the definition: +PHP-DI would inject an instance of `Bar` using autowiring. Attributes have a higher priority, we can use it to override the definition: ```php +use DI\Attribute\Inject; + class Foo { - /** - * @Inject({"my.specific.service"}) - */ + #[Inject(['my.specific.service'])] public function __construct(Bar $param1) { } } ``` -You can go even further by overriding annotations and autowiring using file-based definitions: +You can go even further by overriding attributes and autowiring using file-based definitions: ```php return [ @@ -61,7 +61,7 @@ If we had another definition file (registered after this one), we could override `DI\create()` overrides completely any previous definition or even autowiring. It doesn't allow extending another definition. See the "decorators" section below if you want to do that. -If an object is built using autowiring (or annotations), you can override specific parameters with `DI\autowire()`: +If an object is built using autowiring (with or without attributes), you can override specific parameters with `DI\autowire()`: ```php class Foo diff --git a/doc/definition.md b/doc/definition.md index b40fb97bb..f5413b846 100644 --- a/doc/definition.md +++ b/doc/definition.md @@ -8,7 +8,7 @@ current_menu: definition-introduction To let PHP-DI know what to inject and where, you have several options: - use [autowiring](autowiring.md) -- use [annotations](annotations.md) +- use [attributes](attributes.md) - use [PHP definitions](php-definitions.md) You can also use several or all these options at the same time if you want to. @@ -17,7 +17,7 @@ If you combine several sources, there are priorities that apply. From the highes - Explicit definition on the container (i.e. defined with `$container->set()`) - PHP file definitions (if you add several configuration files, then the last one can override entries from the previous ones) -- Annotations +- PHP attributes - Autowiring Read more in the [Definition overriding documentation](definition-overriding.md) @@ -27,9 +27,9 @@ Read more in the [Definition overriding documentation](definition-overriding.md) See the dedicated documentation about [autowiring](autowiring.md). -## Annotations +## Attributes -See the dedicated documentation about [annotations](annotations.md). +See the dedicated documentation about [attributes](attributes.md). ## PHP configuration diff --git a/doc/frameworks/silex.md b/doc/frameworks/silex.md index a34d95038..81154a4f7 100644 --- a/doc/frameworks/silex.md +++ b/doc/frameworks/silex.md @@ -33,7 +33,7 @@ $app->run(); ## Benefits -Using PHP-DI in Silex allows you to use all the awesome features of PHP-DI to wire your dependencies (using the definition files, autowiring, annotations, …). +Using PHP-DI in Silex allows you to use all the awesome features of PHP-DI to wire your dependencies (using the definition files, autowiring, attributes, …). Another big benefit of the PHP-DI integration is the ability to use dependency injection inside controllers, middlewares and param converters: diff --git a/doc/frameworks/slim.md b/doc/frameworks/slim.md index 5927c89ba..7c7d93eb7 100644 --- a/doc/frameworks/slim.md +++ b/doc/frameworks/slim.md @@ -85,7 +85,7 @@ class UserController $app->delete('/user/{id}', [UserController::class, 'delete']); ``` -Dependencies can then be injected in your controller using [autowiring, PHP-DI config files or even annotations](../definition.md). +Dependencies can then be injected in your controller using [autowiring, PHP-DI config files or even PHP attributes](../definition.md). ### Controller parameters diff --git a/doc/frameworks/symfony2.md b/doc/frameworks/symfony2.md index 76b85741e..74fb3e095 100644 --- a/doc/frameworks/symfony2.md +++ b/doc/frameworks/symfony2.md @@ -76,11 +76,11 @@ class ProductController Example with property injection: ```php +use DI\Attribute\Inject; + class ProductController { - /** - * @Inject - */ + #[Inject] private ProductService $productService; public function clearAction() @@ -148,17 +148,15 @@ services: ### Service name aliases -PHP-DI can also work with autowiring or annotations. These rely on the fact that the service name +PHP-DI can also work with autowiring or PHP attributes. These rely on the fact that the service name is the class name (or interface name), e.g. you reference the entity manager by its class name instead of `doctrine.orm.entity_manager`. -If you want to enjoy autowiring or annotations, you can simplify your life and write simple aliases +If you want to enjoy autowiring or attributes, you can simplify your life and write simple aliases like these: ```php return [ - 'Psr\Log\LoggerInterface' => DI\get('logger'), - // PHP 5.5 notation: ObjectManager::class => DI\get('doctrine.orm.entity_manager'), ]; ``` diff --git a/doc/frameworks/zf1.md b/doc/frameworks/zf1.md index 14205d345..b7ce0bb88 100644 --- a/doc/frameworks/zf1.md +++ b/doc/frameworks/zf1.md @@ -22,7 +22,7 @@ To use PHP-DI in your ZF1 application, you need to change the Dispatcher used by protected function _initContainer() { $builder = new \DI\ContainerBuilder(); - $builder->useAnnotations(true); + $builder->useAttributes(true); $container = $builder->build(); $dispatcher = new \DI\Bridge\ZendFramework1\Dispatcher(); @@ -34,8 +34,6 @@ To use PHP-DI in your ZF1 application, you need to change the Dispatcher used by That's it! -As you can see since PHP-DI 5 it's necessary to enable [annotations](../annotations.md) because they are disabled by default. - **Warning**: if you use Zend's autoloader (and not Composer), you will need to configure it: ```php @@ -53,8 +51,8 @@ class GuestbookController extends Zend_Controller_Action { /** * This dependency will be injected by PHP-DI - * @Inject */ + #[Inject] private Application_Service_GuestbookService $guestbookService; public function indexAction() diff --git a/doc/frameworks/zf2.md b/doc/frameworks/zf2.md index b46fb261c..e8de919ac 100644 --- a/doc/frameworks/zf2.md +++ b/doc/frameworks/zf2.md @@ -35,21 +35,19 @@ Register it in `application_root/config/application.config.php`: That's it! -If you want to use annotations, please read the "Configuration" section below. - ## Usage Now you can inject dependencies in your controllers. -Here is an example of the GuestbookController of the quickstart (using annotations): +Here is an example of the GuestbookController of the quickstart (using attributes): ```php class GuestbookController extends AbstractActionController { /** * This dependency will be injected by PHP-DI - * @Inject */ + #[Inject] private \Application\Service\GuestbookService $guestbookService; public function indexAction() @@ -82,18 +80,6 @@ return [ ]; ``` -### Enable or disable annotations - -Annotations are disabled by default since PHP-DI 5. To enable them, use the following config: - -```php -return [ - 'phpdi-zf2' => [ - 'useAnnotations' => true, - ] -]; -``` - ### Override definitions file location ```php diff --git a/doc/getting-started.md b/doc/getting-started.md index f0e33c082..c974d1b35 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -107,7 +107,7 @@ Don't worry, PHP-DI uses [PHP's Reflection classes](http://php.net/manual/en/boo We have seen **autowiring**, which is when PHP-DI figures out automatically the dependencies a class needs. But we have 3 ways to define what to inject in a class: - using [autowiring](autowiring.md) -- using [annotations](annotations.md) +- using [attributes](attributes.md) - using [PHP definitions](php-definitions.md) Every one of them is different and optional. Here is an example of PHP definitions in a file: @@ -123,7 +123,7 @@ return [ ]; ``` -Please read the [Defining injections](definition.md) documentation to learn about autowiring, annotations and PHP definitions. +Please read the [Defining injections](definition.md) documentation to learn about autowiring, attributes and PHP definitions. ## Framework integration diff --git a/doc/lazy-injection.md b/doc/lazy-injection.md index dea7a9e06..2b63b1fe6 100644 --- a/doc/lazy-injection.md +++ b/doc/lazy-injection.md @@ -102,12 +102,12 @@ return [ ]; ``` -### Annotations +### Attributes ```php -/** - * @Injectable(lazy=true) - */ +use DI\Attribute\Injectable; + +#[Injectable(lazy: true)] class MyClass { } diff --git a/doc/migration/7.0.md b/doc/migration/7.0.md index 59d6cc64d..e45a2f283 100644 --- a/doc/migration/7.0.md +++ b/doc/migration/7.0.md @@ -33,14 +33,22 @@ Related to that: `\DI\ContainerBuilder::buildDevContainer()` method is now obsol + $container = new \DI\Container(); ``` -## PHPdoc types are ignored by `@Inject` +## Annotations (`@Inject`) have been replaced by PHP attributes (`#[Inject]`) -Now that PHP 7.4 and up supports typed properties, PHP-DI will stop reading types from phpdoc. +Now that PHP 8.0 and up [supports attributes natively](https://www.php.net/manual/fr/language.attributes.overview.php), these are read instead of phpdoc annotations. + +Additionally, now that PHP supports typed properties, PHP-DI will stop reading types from phpdoc. Here is an example on how to migrate from PHP-DI 6 to PHP-DI 7: - **before:** +```php +// Container configuration +$containerBuilder = new \DI\ContainerBuilder; +$containerBuilder->useAnnotations(); +``` + ```php class Example { @@ -63,22 +71,28 @@ class Example - **after:** ```php +// Container configuration +$containerBuilder = new \DI\ContainerBuilder; +$containerBuilder->useAttributes(); +``` + +```php +use DI\Attribute\Inject; + class Example { - /** - * @Inject - */ + #[Inject] private Foo $property; - /** - * @Inject - */ + #[Inject] public function method(Foo $param) { } } ``` +Read more about attributes in the PHP-DI documentation: [PHP-DI attributes](../attributes.md). + ## Internal changes If you were overriding or extending some internal classes of PHP-DI, be aware that they may have changed. diff --git a/doc/performances.md b/doc/performances.md index 9167da1c5..3629d8c87 100644 --- a/doc/performances.md +++ b/doc/performances.md @@ -13,7 +13,7 @@ PHP-DI 4 and 5 relied a lot on caching. With PHP-DI 6 the main vector for optimi PHP-DI performs two tasks that can be expensive: -- reading definitions from your [configuration](php-definitions.md), from [autowiring](autowiring.md) or from [annotations](annotations.md) +- reading definitions from your [configuration](php-definitions.md), from [autowiring](autowiring.md) or from [attributes](attributes.md) - resolving those definitions to create your services In order to avoid those two tasks, the container can be compiled into PHP code optimized especially for your configuration and your classes. @@ -43,7 +43,7 @@ If your production handles a lot of traffic you may also want to generate the co ### Development environment -**Do not compile the container in a development environment**, else all the changes you make to the definitions (annotations, configuration files, etc.) will not be taken into account. Here is an example of what you can do: +**Do not compile the container in a development environment**, else all the changes you make to the definitions (attributes, configuration files, etc.) will not be taken into account. Here is an example of what you can do: ```php $containerBuilder = new \DI\ContainerBuilder(); @@ -120,7 +120,7 @@ Compiling the container is the most efficient solution, but it has some limits. - wildcard definitions - usage of `Container::make()` or `Container::injectOn()` (because those are not using the compiled code) -If you make heavy use of those features, and if it slows down your application you can enable the caching system. The cache will ensure annotations or the reflection is not read again on every request. +If you make heavy use of those features, and if it slows down your application you can enable the caching system. The cache will ensure the reflection is not read again on every request. The cache relies on APCu directly because it is the only cache system that makes sense (very fast to write and read). Other caches are not good options, this is why PHP-DI does not use PSR-6 or PSR-16 for this cache. @@ -135,5 +135,5 @@ if (/* is production */) { Heads up: -- do not use a cache in a development environment, else changes you make to the definitions (annotations, configuration files, etc.) may not be taken into account +- do not use a cache in a development environment, else changes you make to the definitions (attributes, configuration files, etc.) may not be taken into account - clear the APCu cache on each deployment in production (to avoid using a stale cache) diff --git a/doc/php-definitions.md b/doc/php-definitions.md index 508100130..864b42162 100644 --- a/doc/php-definitions.md +++ b/doc/php-definitions.md @@ -5,7 +5,7 @@ current_menu: php-definitions # PHP definitions -On top of [autowiring](autowiring.md) and [annotations](annotations.md), you can use **a PHP configuration format** to define injections. +On top of [autowiring](autowiring.md) and [attributes](attributes.md), you can use **a PHP configuration format** to define injections. You can register that configuration as an array: diff --git a/src/Annotation/Inject.php b/src/Annotation/Inject.php deleted file mode 100644 index cc3f7d550..000000000 --- a/src/Annotation/Inject.php +++ /dev/null @@ -1,91 +0,0 @@ - - */ -final class Inject -{ - /** - * Entry name. - */ - private ?string $name = null; - - /** - * Parameters, indexed by the parameter number (index) or name. - * - * Used if the annotation is set on a method - */ - private array $parameters = []; - - /** - * @throws InvalidAnnotation - */ - public function __construct(array $values) - { - // Process the parameters as a list AND as a parameter array (we don't know on what the annotation is) - - // @Inject(name="foo") - if (isset($values['name']) && is_string($values['name'])) { - $this->name = $values['name']; - - return; - } - - // @Inject - if (! isset($values['value'])) { - return; - } - - $values = $values['value']; - - // @Inject("foo") - if (is_string($values)) { - $this->name = $values; - } - - // @Inject({...}) on a method - if (is_array($values)) { - foreach ($values as $key => $value) { - if (! is_string($value)) { - throw new InvalidAnnotation(sprintf( - '@Inject({"param" = "value"}) expects "value" to be a string, %s given.', - json_encode($value) - )); - } - - $this->parameters[$key] = $value; - } - } - } - - /** - * @return string|null Name of the entry to inject - */ - public function getName() : string|null - { - return $this->name; - } - - /** - * @return array Parameters, indexed by the parameter number (index) or name - */ - public function getParameters() : array - { - return $this->parameters; - } -} diff --git a/src/Annotation/Injectable.php b/src/Annotation/Injectable.php deleted file mode 100644 index ddab369bc..000000000 --- a/src/Annotation/Injectable.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @author Matthieu Napoli - */ -final class Injectable -{ - /** - * Should the object be lazy-loaded. - */ - private ?bool $lazy = null; - - public function __construct(array $values) - { - if (isset($values['lazy'])) { - $this->lazy = (bool) $values['lazy']; - } - } - - public function isLazy() : bool|null - { - return $this->lazy; - } -} diff --git a/src/Attribute/Inject.php b/src/Attribute/Inject.php index 988cb738e..34339d2df 100644 --- a/src/Attribute/Inject.php +++ b/src/Attribute/Inject.php @@ -5,7 +5,7 @@ namespace DI\Attribute; use Attribute; -use DI\Definition\Exception\InvalidAnnotation; +use DI\Definition\Exception\InvalidAttribute; /** * #[Inject] attribute. @@ -27,12 +27,12 @@ final class Inject /** * Parameters, indexed by the parameter number (index) or name. * - * Used if the annotation is set on a method + * Used if the attribute is set on a method */ private array $parameters = []; /** - * @throws InvalidAnnotation + * @throws InvalidAttribute */ public function __construct(string|array|null $name = null) { @@ -45,7 +45,7 @@ public function __construct(string|array|null $name = null) if (is_array($name)) { foreach ($name as $key => $value) { if (! is_string($value)) { - throw new InvalidAnnotation(sprintf( + throw new InvalidAttribute(sprintf( "#[Inject(['param' => 'value'])] expects \"value\" to be a string, %s given.", json_encode($value, \JSON_THROW_ON_ERROR) )); diff --git a/src/Attribute/Injectable.php b/src/Attribute/Injectable.php index 2acb78326..86dfdd4b4 100644 --- a/src/Attribute/Injectable.php +++ b/src/Attribute/Injectable.php @@ -7,7 +7,7 @@ use Attribute; /** - * "Injectable" annotation. + * "Injectable" attribute. * * Marks a class as injectable * diff --git a/src/ContainerBuilder.php b/src/ContainerBuilder.php index f27f6736d..a582e3714 100644 --- a/src/ContainerBuilder.php +++ b/src/ContainerBuilder.php @@ -5,7 +5,6 @@ namespace DI; use DI\Compiler\Compiler; -use DI\Definition\Source\AnnotationBasedAutowiring; use DI\Definition\Source\AttributeBasedAutowiring; use DI\Definition\Source\DefinitionArray; use DI\Definition\Source\DefinitionFile; @@ -49,8 +48,6 @@ class ContainerBuilder private bool $useAutowiring = true; - private bool $useAnnotations = false; - private bool $useAttributes = false; /** @@ -100,9 +97,6 @@ public function build() if ($this->useAttributes) { $autowiring = new AttributeBasedAutowiring; $sources[] = $autowiring; - } elseif ($this->useAnnotations) { - $autowiring = new AnnotationBasedAutowiring; - $sources[] = $autowiring; } elseif ($this->useAutowiring) { $autowiring = new ReflectionBasedAutowiring; $sources[] = $autowiring; @@ -147,7 +141,7 @@ public function build() $this->compileToDirectory, $containerClass, $this->containerParentClass, - $this->useAutowiring || $this->useAnnotations + $this->useAutowiring ); // Only load the file if it hasn't been already loaded // (the container can be created multiple times in the same process) @@ -207,22 +201,6 @@ public function useAutowiring(bool $bool) : self return $this; } - /** - * Enable or disable the use of annotations to guess injections. - * - * Disabled by default. - * - * @return $this - */ - public function useAnnotations(bool $bool) : self - { - $this->ensureNotLocked(); - - $this->useAnnotations = $bool; - - return $this; - } - /** * Enable or disable the use of PHP 8 attributes to configure injections. * @@ -307,7 +285,7 @@ public function addDefinitions(string|array|DefinitionSource ...$definitions) : * * Before using this feature, you should try these steps first: * - enable compilation if not already done (see `enableCompilation()`) - * - if you use autowiring or annotations, add all the classes you are using into your configuration so that + * - if you use autowiring or attributes, add all the classes you are using into your configuration so that * PHP-DI knows about them and compiles them * Once this is done, you can try to optimize performances further with APCu. It can also be useful if you use * `Container::make()` instead of `get()` (`make()` calls cannot be compiled so they are not optimized). diff --git a/src/Definition/Exception/InvalidAnnotation.php b/src/Definition/Exception/InvalidAttribute.php similarity index 57% rename from src/Definition/Exception/InvalidAnnotation.php rename to src/Definition/Exception/InvalidAttribute.php index 630c34a08..4504f18ab 100644 --- a/src/Definition/Exception/InvalidAnnotation.php +++ b/src/Definition/Exception/InvalidAttribute.php @@ -5,10 +5,10 @@ namespace DI\Definition\Exception; /** - * Error in the definitions using annotations. + * Error in the definitions using PHP attributes. * * @author Matthieu Napoli */ -class InvalidAnnotation extends InvalidDefinition +class InvalidAttribute extends InvalidDefinition { } diff --git a/src/Definition/Helper/AutowireDefinitionHelper.php b/src/Definition/Helper/AutowireDefinitionHelper.php index 7d548672c..01b59e8fe 100644 --- a/src/Definition/Helper/AutowireDefinitionHelper.php +++ b/src/Definition/Helper/AutowireDefinitionHelper.php @@ -18,9 +18,9 @@ class AutowireDefinitionHelper extends CreateDefinitionHelper /** * Defines a value for a specific argument of the constructor. * - * This method is usually used together with annotations or autowiring, when a parameter + * This method is usually used together with attributes or autowiring, when a parameter * is not (or cannot be) type-hinted. Using this method instead of constructor() allows to - * avoid defining all the parameters (letting them being resolved using annotations or autowiring) + * avoid defining all the parameters (letting them being resolved using attributes or autowiring) * and only define one. * * @param string|int $parameter Parameter name of position for which the value will be given. @@ -38,9 +38,9 @@ public function constructorParameter(string|int $parameter, mixed $value) : self /** * Defines a method to call and a value for a specific argument. * - * This method is usually used together with annotations or autowiring, when a parameter + * This method is usually used together with attributes or autowiring, when a parameter * is not (or cannot be) type-hinted. Using this method instead of method() allows to - * avoid defining all the parameters (letting them being resolved using annotations or + * avoid defining all the parameters (letting them being resolved using attributes or * autowiring) and only define one. * * If multiple calls to the method have been configured already (e.g. in a previous definition) diff --git a/src/Definition/Helper/FactoryDefinitionHelper.php b/src/Definition/Helper/FactoryDefinitionHelper.php index a6906c85a..85e1ba525 100644 --- a/src/Definition/Helper/FactoryDefinitionHelper.php +++ b/src/Definition/Helper/FactoryDefinitionHelper.php @@ -44,7 +44,7 @@ public function getDefinition(string $entryName) : FactoryDefinition /** * Defines arguments to pass to the factory. * - * Because factory methods do not yet support annotations or autowiring, this method + * Because factory methods do not yet support attributes or autowiring, this method * should be used to define all parameters except the ContainerInterface and RequestedEntry. * * Multiple calls can be made to the method to override individual values. diff --git a/src/Definition/Source/AnnotationBasedAutowiring.php b/src/Definition/Source/AnnotationBasedAutowiring.php deleted file mode 100644 index 1d01c4d84..000000000 --- a/src/Definition/Source/AnnotationBasedAutowiring.php +++ /dev/null @@ -1,273 +0,0 @@ - - */ -class AnnotationBasedAutowiring implements DefinitionSource, Autowiring -{ - private ?Reader $annotationReader = null; - - /** - * @throws InvalidAnnotation - */ - public function autowire(string $name, ObjectDefinition $definition = null) : ObjectDefinition|null - { - $className = $definition ? $definition->getClassName() : $name; - - if (!class_exists($className) && !interface_exists($className)) { - return $definition; - } - - $definition = $definition ?: new ObjectDefinition($name); - - $class = new ReflectionClass($className); - - $this->readInjectableAnnotation($class, $definition); - - // Browse the class properties looking for annotated properties - $this->readProperties($class, $definition); - - // Browse the object's methods looking for annotated methods - $this->readMethods($class, $definition); - - return $definition; - } - - /** - * {@inheritdoc} - * @throws InvalidAnnotation - * @throws InvalidArgumentException The class doesn't exist - */ - public function getDefinition(string $name) : ObjectDefinition|null - { - return $this->autowire($name); - } - - /** - * Autowiring cannot guess all existing definitions. - */ - public function getDefinitions() : array - { - return []; - } - - /** - * Browse the class properties looking for annotated properties. - */ - private function readProperties(ReflectionClass $class, ObjectDefinition $definition) : void - { - foreach ($class->getProperties() as $property) { - if ($property->isStatic()) { - continue; - } - $this->readProperty($property, $definition); - } - - // Read also the *private* properties of the parent classes - /** @noinspection PhpAssignmentInConditionInspection */ - while ($class = $class->getParentClass()) { - foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE) as $property) { - if ($property->isStatic()) { - continue; - } - $this->readProperty($property, $definition, $class->getName()); - } - } - } - - /** - * @throws InvalidAnnotation - */ - private function readProperty(ReflectionProperty $property, ObjectDefinition $definition, ?string $classname = null) : void - { - // Look for @Inject annotation - $annotation = $this->getAnnotationReader()->getPropertyAnnotation($property, Inject::class); - if (!$annotation instanceof Inject) { - return; - } - - // Try to @Inject("name") or look for the property type - $entryName = $annotation->getName(); - - // Try using typed properties - $propertyType = $property->getType(); - if ($entryName === null && $propertyType instanceof ReflectionNamedType) { - if (! class_exists($propertyType->getName()) && ! interface_exists($propertyType->getName())) { - throw new InvalidAnnotation(sprintf( - '@Inject found on property %s::%s but unable to guess what to inject, the type of the property does not look like a valid class or interface name', - $property->getDeclaringClass()->getName(), - $property->getName() - )); - } - $entryName = $propertyType->getName(); - } - - if ($entryName === null) { - throw new InvalidAnnotation(sprintf( - '@Inject found on property %s::%s but unable to guess what to inject, please add a type to the property', - $property->getDeclaringClass()->getName(), - $property->getName() - )); - } - - $definition->addPropertyInjection( - new PropertyInjection($property->getName(), new Reference($entryName), $classname) - ); - } - - /** - * Browse the object's methods looking for annotated methods. - */ - private function readMethods(ReflectionClass $class, ObjectDefinition $objectDefinition) : void - { - // This will look in all the methods, including those of the parent classes - foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - if ($method->isStatic()) { - continue; - } - - $methodInjection = $this->getMethodInjection($method); - - if (! $methodInjection) { - continue; - } - - if ($method->isConstructor()) { - $objectDefinition->completeConstructorInjection($methodInjection); - } else { - $objectDefinition->completeFirstMethodInjection($methodInjection); - } - } - } - - /** - * @throws InvalidAnnotation - */ - private function getMethodInjection(ReflectionMethod $method) : ?MethodInjection - { - // Look for @Inject annotation - try { - $annotation = $this->getAnnotationReader()->getMethodAnnotation($method, Inject::class); - } catch (InvalidAnnotation $e) { - throw new InvalidAnnotation(sprintf( - '@Inject annotation on %s::%s is malformed. %s', - $method->getDeclaringClass()->getName(), - $method->getName(), - $e->getMessage() - ), 0, $e); - } - - // @Inject on constructor is implicit - if (! ($annotation || $method->isConstructor())) { - return null; - } - - $annotationParameters = $annotation instanceof Inject ? $annotation->getParameters() : []; - - $parameters = []; - foreach ($method->getParameters() as $index => $parameter) { - $entryName = $this->getMethodParameter($index, $parameter, $annotationParameters); - - if ($entryName !== null) { - $parameters[$index] = new Reference($entryName); - } - } - - if ($method->isConstructor()) { - return MethodInjection::constructor($parameters); - } - - return new MethodInjection($method->getName(), $parameters); - } - - /** - * @return string|null Entry name or null if not found. - */ - private function getMethodParameter(int $parameterIndex, ReflectionParameter $parameter, array $annotationParameters) : string|null - { - // @Inject has definition for this parameter (by index, or by name) - if (isset($annotationParameters[$parameterIndex])) { - return $annotationParameters[$parameterIndex]; - } - if (isset($annotationParameters[$parameter->getName()])) { - return $annotationParameters[$parameter->getName()]; - } - - // Skip optional parameters if not explicitly defined - if ($parameter->isOptional()) { - return null; - } - - // Look for the property type - $parameterType = $parameter->getType(); - if ($parameterType instanceof ReflectionNamedType && !$parameterType->isBuiltin()) { - return $parameterType->getName(); - } - - return null; - } - - public function getAnnotationReader() : Reader - { - if ($this->annotationReader === null) { - AnnotationRegistry::registerLoader('class_exists'); - $this->annotationReader = new SimpleAnnotationReader(); - $this->annotationReader->addNamespace('DI\Annotation'); - } - - return $this->annotationReader; - } - - /** - * @throws InvalidAnnotation - */ - private function readInjectableAnnotation(ReflectionClass $class, ObjectDefinition $definition) : void - { - try { - /** @var Injectable|null $annotation */ - $annotation = $this->getAnnotationReader() - ->getClassAnnotation($class, Injectable::class); - } catch (UnexpectedValueException $e) { - throw new InvalidAnnotation(sprintf( - 'Error while reading @Injectable on %s: %s', - $class->getName(), - $e->getMessage() - ), 0, $e); - } - - if (! $annotation) { - return; - } - - if ($annotation->isLazy() !== null) { - $definition->setLazy($annotation->isLazy()); - } - } -} diff --git a/src/Definition/Source/AttributeBasedAutowiring.php b/src/Definition/Source/AttributeBasedAutowiring.php index b72d72d75..709759816 100644 --- a/src/Definition/Source/AttributeBasedAutowiring.php +++ b/src/Definition/Source/AttributeBasedAutowiring.php @@ -6,7 +6,7 @@ use DI\Attribute\Inject; use DI\Attribute\Injectable; -use DI\Definition\Exception\InvalidAnnotation; +use DI\Definition\Exception\InvalidAttribute; use DI\Definition\ObjectDefinition; use DI\Definition\ObjectDefinition\MethodInjection; use DI\Definition\ObjectDefinition\PropertyInjection; @@ -28,15 +28,8 @@ */ class AttributeBasedAutowiring implements DefinitionSource, Autowiring { - public function __construct() - { - if (\PHP_VERSION_ID < 80000) { - throw new \Exception('Using PHP 8 attributes for autowiring is only supported with PHP 8'); - } - } - /** - * @throws InvalidAnnotation + * @throws InvalidAttribute */ public function autowire(string $name, ObjectDefinition $definition = null) : ObjectDefinition|null { @@ -63,7 +56,7 @@ public function autowire(string $name, ObjectDefinition $definition = null) : Ob /** * {@inheritdoc} - * @throws InvalidAnnotation + * @throws InvalidAttribute * @throws InvalidArgumentException The class doesn't exist */ public function getDefinition(string $name) : ObjectDefinition|null @@ -104,11 +97,11 @@ private function readProperties(ReflectionClass $class, ObjectDefinition $defini } /** - * @throws InvalidAnnotation + * @throws InvalidAttribute */ private function readProperty(ReflectionProperty $property, ObjectDefinition $definition, ?string $classname = null) : void { - // Look for #[Inject] annotation + // Look for #[Inject] attribute try { $attribute = $property->getAttributes(Inject::class)[0] ?? null; if (! $attribute) { @@ -117,7 +110,7 @@ private function readProperty(ReflectionProperty $property, ObjectDefinition $de /** @var Inject $inject */ $inject = $attribute->newInstance(); } catch (Throwable $e) { - throw new InvalidAnnotation(sprintf( + throw new InvalidAttribute(sprintf( '#[Inject] annotation on property %s::%s is malformed. %s', $property->getDeclaringClass()->getName(), $property->getName(), @@ -132,7 +125,7 @@ private function readProperty(ReflectionProperty $property, ObjectDefinition $de $propertyType = $property->getType(); if ($entryName === null && $propertyType instanceof ReflectionNamedType) { if (! class_exists($propertyType->getName()) && ! interface_exists($propertyType->getName())) { - throw new InvalidAnnotation(sprintf( + throw new InvalidAttribute(sprintf( '#[Inject] found on property %s::%s but unable to guess what to inject, the type of the property does not look like a valid class or interface name', $property->getDeclaringClass()->getName(), $property->getName() @@ -142,7 +135,7 @@ private function readProperty(ReflectionProperty $property, ObjectDefinition $de } if ($entryName === null) { - throw new InvalidAnnotation(sprintf( + throw new InvalidAttribute(sprintf( '#[Inject] found on property %s::%s but unable to guess what to inject, please add a type to the property', $property->getDeclaringClass()->getName(), $property->getName() @@ -248,7 +241,7 @@ private function getMethodParameter(int $parameterIndex, ReflectionParameter $pa } /** - * @throws InvalidAnnotation + * @throws InvalidAttribute */ private function readInjectableAttribute(ReflectionClass $class, ObjectDefinition $definition) : void { @@ -259,7 +252,7 @@ private function readInjectableAttribute(ReflectionClass $class, ObjectDefinitio } $attribute = $attribute->newInstance(); } catch (Throwable $e) { - throw new InvalidAnnotation(sprintf( + throw new InvalidAttribute(sprintf( 'Error while reading #[Injectable] on %s: %s', $class->getName(), $e->getMessage() diff --git a/tests/IntegrationTest/Annotations/A.php b/tests/IntegrationTest/Annotations/A.php deleted file mode 100644 index d5129f243..000000000 --- a/tests/IntegrationTest/Annotations/A.php +++ /dev/null @@ -1,9 +0,0 @@ -useAnnotations(true); - - /** @var B $object */ - $object = $builder->build()->get(B::class); - - $this->assertInstanceOf(A::class, $object->public); - $this->assertInstanceOf(A::class, $object->getProtected()); - $this->assertInstanceOf(A::class, $object->getPrivate()); - } - - /** - * Inject in parent properties (public, protected and private). - * - * @test - * @dataProvider provideContainer - */ - public function inject_in_parent_properties(ContainerBuilder $builder) - { - $builder->useAnnotations(true); - $container = $builder->build(); - - /** @var C $object */ - $object = $container->get(C::class); - $this->assertInstanceOf(A::class, $object->public); - $this->assertInstanceOf(A::class, $object->getProtected()); - $this->assertInstanceOf(A::class, $object->getPrivate()); - - /** @var D $object */ - $object = $container->get(D::class); - $this->assertInstanceOf(A::class, $object->public); - $this->assertInstanceOf(A::class, $object->getProtected()); - $this->assertInstanceOf(A::class, $object->getPrivate()); - } - - /** - * Inject in private parent properties even if they have the same name of child properties. - * - * @test - * @dataProvider provideContainer - */ - public function inject_in_private_parent_properties_with_same_name(ContainerBuilder $builder) - { - $builder->useAnnotations(true); - $container = $builder->build(); - - /** @var Child $object */ - $object = $container->get(Child::class); - $this->assertInstanceOf(A::class, $object->public); - $this->assertInstanceOf(A::class, $object->getProtected()); - $this->assertInstanceOf(A::class, $object->getPrivate()); - $this->assertInstanceOf(A::class, $object->getChildPrivate()); - } - - /** - * @test - * @dataProvider provideContainer - */ - public function inject_by_name(ContainerBuilder $builder) - { - $builder->useAnnotations(true); - - $dependency = new \stdClass(); - - $builder->addDefinitions([ - 'namedDependency' => $dependency, - ]); - $container = $builder->build(); - - /** @var NamedInjection $object */ - $object = $container->get(NamedInjection::class); - $this->assertSame($dependency, $object->dependency); - } - - /** - * @test - * @dataProvider provideContainer - */ - public function errors_if_dependency_by_name_not_found(ContainerBuilder $builder) - { - $this->expectException(DependencyException::class); - $builder->useAnnotations(true); - $builder->build()->get(NamedInjection::class); - } -} diff --git a/tests/IntegrationTest/Annotations/B.php b/tests/IntegrationTest/Annotations/B.php deleted file mode 100644 index 05aa88694..000000000 --- a/tests/IntegrationTest/Annotations/B.php +++ /dev/null @@ -1,35 +0,0 @@ -protected; - } - - public function getPrivate() - { - return $this->private; - } -} diff --git a/tests/IntegrationTest/Annotations/C.php b/tests/IntegrationTest/Annotations/C.php deleted file mode 100644 index 031b98284..000000000 --- a/tests/IntegrationTest/Annotations/C.php +++ /dev/null @@ -1,9 +0,0 @@ -private; - } -} diff --git a/tests/IntegrationTest/Annotations/D.php b/tests/IntegrationTest/Annotations/D.php deleted file mode 100644 index 046027951..000000000 --- a/tests/IntegrationTest/Annotations/D.php +++ /dev/null @@ -1,9 +0,0 @@ -expectException(DependencyException::class); $this->expectExceptionMessage('Circular dependency detected while trying to resolve entry \'DI\Test\UnitTest\Fixtures\Class1CircularDependencies\''); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->build()->get(Class1CircularDependencies::class); } diff --git a/tests/IntegrationTest/ContainerInjectOnTest.php b/tests/IntegrationTest/ContainerInjectOnTest.php index e2500fa1f..b5bac0e91 100644 --- a/tests/IntegrationTest/ContainerInjectOnTest.php +++ b/tests/IntegrationTest/ContainerInjectOnTest.php @@ -4,6 +4,7 @@ namespace DI\Test\IntegrationTest; +use DI\Attribute\Inject; use DI\ContainerBuilder; use DI\Test\IntegrationTest\Fixtures\Class1; use DI\Test\IntegrationTest\Fixtures\Class2; @@ -33,10 +34,10 @@ public function test_returns_the_same_object(ContainerBuilder $builder) /** * @dataProvider provideContainer */ - public function test_inject_on_object_using_annotations(ContainerBuilder $builder) + public function test_inject_on_object_using_attributes(ContainerBuilder $builder) { $builder->useAutowiring(true); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ 'foo' => 'bar', Interface1::class => create(Implementation1::class), @@ -66,7 +67,7 @@ public function test_inject_on_object_using_annotations(ContainerBuilder $builde self::assertInstanceOf(Class2::class, $obj->method1Param1); // Method 2 (automatic resolution with type hinting) self::assertInstanceOf(Implementation1::class, $obj->method2Param1); - // Method 3 (defining parameters with the annotation) + // Method 3 (defining parameters with the attribute) self::assertInstanceOf(Class2::class, $obj->method3Param1); self::assertEquals('bar', $obj->method3Param2); // Method 4 (lazy) @@ -84,7 +85,7 @@ public function test_inject_on_object_using_annotations(ContainerBuilder $builde public function test_inject_on_object_using_config(ContainerBuilder $builder) { $builder->useAutowiring(false); - $builder->useAnnotations(false); + $builder->useAttributes(false); $builder->addDefinitions([ 'foo' => 'bar', @@ -136,7 +137,7 @@ public function test_inject_on_object_using_config(ContainerBuilder $builder) self::assertInstanceOf(Class2::class, $obj->method1Param1); // Method 2 (automatic resolution with type hinting) self::assertInstanceOf(Implementation1::class, $obj->method2Param1); - // Method 3 (defining parameters with the annotation) + // Method 3 (defining parameters with the attribute) self::assertInstanceOf(Class2::class, $obj->method3Param1); self::assertEquals('bar', $obj->method3Param2); // Method 4 (lazy) @@ -154,23 +155,19 @@ public function test_inject_on_object_using_config(ContainerBuilder $builder) public function testInjectOnAnonClass(ContainerBuilder $builder) { $obj = new class { - /** - * @Inject - */ + #[Inject] public Class2 $property; public $methodParam; - /** - * @Inject - */ + #[Inject] public function setParam(Class2 $param) { $this->methodParam = $param; } }; - $builder->useAnnotations(true); + $builder->useAttributes(true); $container = $builder->build(); $container->injectOn($obj); diff --git a/tests/IntegrationTest/ContainerMakeTest.php b/tests/IntegrationTest/ContainerMakeTest.php index 1e9a9563f..65b0ee7bd 100644 --- a/tests/IntegrationTest/ContainerMakeTest.php +++ b/tests/IntegrationTest/ContainerMakeTest.php @@ -72,7 +72,7 @@ public function testCircularDependencyException(ContainerBuilder $builder) { $this->expectException(DependencyException::class); $this->expectExceptionMessage('Circular dependency detected while trying to resolve entry \'DI\Test\UnitTest\Fixtures\Class1CircularDependencies\''); - $builder->useAnnotations(true); + $builder->useAttributes(true); $container = $builder->build(); $container->make(Class1CircularDependencies::class); } diff --git a/tests/IntegrationTest/Definitions/AnnotationTest.php b/tests/IntegrationTest/Definitions/AnnotationTest.php deleted file mode 100644 index 9b1143c27..000000000 --- a/tests/IntegrationTest/Definitions/AnnotationTest.php +++ /dev/null @@ -1,189 +0,0 @@ -useAnnotations(true)->build(); - self::assertInstanceOf(NonAnnotatedClass::class, $container->get(NonAnnotatedClass::class)); - } - - /** - * @dataProvider provideContainer - */ - public function test_constructor_injection(ContainerBuilder $builder) - { - $builder->useAnnotations(true); - $builder->addDefinitions([ - 'foo' => 'bar', - 'lazyService' => autowire(\stdClass::class)->lazy(), - ]); - $container = $builder->build(); - - $object = $container->get(ConstructorInjection::class); - - self::assertEquals(new \stdClass, $object->typedValue); - self::assertEquals(new \stdClass, $object->typedOptionalValue); - self::assertEquals('bar', $object->value); - self::assertInstanceOf(\stdClass::class, $object->lazyService); - self::assertInstanceOf(LazyLoadingInterface::class, $object->lazyService); - self::assertFalse($object->lazyService->isProxyInitialized()); - self::assertEquals('hello', $object->optionalValue); - } - - /** - * @dataProvider provideContainer - */ - public function test_property_injection(ContainerBuilder $builder) - { - $builder->useAnnotations(true); - $builder->addDefinitions([ - 'foo' => 'bar', - 'lazyService' => autowire(\stdClass::class)->lazy(), - ]); - $container = $builder->build(); - - $object = $container->get(PropertyInjection::class); - - self::assertEquals('bar', $object->value); - self::assertEquals('bar', $object->value2); - self::assertInstanceOf(\stdClass::class, $object->entry); - self::assertInstanceOf(\stdClass::class, $object->lazyService); - self::assertInstanceOf(LazyLoadingInterface::class, $object->lazyService); - self::assertFalse($object->lazyService->isProxyInitialized()); - } - - /** - * @dataProvider provideContainer - */ - public function test_method_injection(ContainerBuilder $builder) - { - $builder->useAnnotations(true); - $builder->addDefinitions([ - 'foo' => 'bar', - 'lazyService' => autowire(\stdClass::class)->lazy(), - ]); - $container = $builder->build(); - - $object = $container->get(ConstructorInjection::class); - - self::assertEquals(new \stdClass, $object->typedValue); - self::assertEquals(new \stdClass, $object->typedOptionalValue); - self::assertEquals('bar', $object->value); - self::assertInstanceOf(\stdClass::class, $object->lazyService); - self::assertInstanceOf(LazyLoadingInterface::class, $object->lazyService); - self::assertFalse($object->lazyService->isProxyInitialized()); - self::assertEquals('hello', $object->optionalValue); - } -} - -namespace DI\Test\IntegrationTest\Definitions\AnnotationTest; - -use DI\Annotation\Inject; -use stdClass; - -class NonAnnotatedClass -{ -} - -class NamespacedClass -{ -} - -class ConstructorInjection -{ - public $value; - public $scalarValue; - public $typedValue; - public $typedOptionalValue; - /** @var \ProxyManager\Proxy\LazyLoadingInterface */ - public $lazyService; - public $optionalValue; - - /** - * @Inject({"value" = "foo", "scalarValue" = "foo", "lazyService" = "lazyService"}) - */ - public function __construct( - $value, - string $scalarValue, - \stdClass $typedValue, - \stdClass $typedOptionalValue = null, - \stdClass $lazyService, - $optionalValue = 'hello' - ) { - $this->value = $value; - $this->scalarValue = $scalarValue; - $this->typedValue = $typedValue; - $this->typedOptionalValue = $typedOptionalValue; - $this->lazyService = $lazyService; - $this->optionalValue = $optionalValue; - } -} - -class PropertyInjection -{ - /** - * @Inject(name="foo") - */ - public $value; - /** - * @Inject("foo") - */ - public $value2; - /** - * @Inject - */ - public stdClass $entry; - /** - * @Inject("lazyService") - */ - public $lazyService; -} - -class MethodInjection -{ - public $value; - public $scalarValue; - public $typedValue; - public $typedOptionalValue; - /** @var \ProxyManager\Proxy\LazyLoadingInterface */ - public $lazyService; - public $optionalValue; - - /** - * @Inject({"value" = "foo", "scalarValue" = "foo", "lazyService" = "lazyService"}) - */ - public function method( - $value, - string $scalarValue, - $untypedValue, - \stdClass $typedOptionalValue = null, - \stdClass $lazyService, - $optionalValue = 'hello' - ) { - $this->value = $value; - $this->scalarValue = $scalarValue; - $this->untypedValue = $untypedValue; - $this->typedOptionalValue = $typedOptionalValue; - $this->lazyService = $lazyService; - $this->optionalValue = $optionalValue; - } -} diff --git a/tests/IntegrationTest/Definitions/AutowireDefinition/ConstructorInjection.php b/tests/IntegrationTest/Definitions/AutowireDefinition/ConstructorInjection.php index 1fe6e0e51..ddc0f751c 100644 --- a/tests/IntegrationTest/Definitions/AutowireDefinition/ConstructorInjection.php +++ b/tests/IntegrationTest/Definitions/AutowireDefinition/ConstructorInjection.php @@ -4,7 +4,7 @@ namespace DI\Test\IntegrationTest\Definitions\AutowireDefinition; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class ConstructorInjection { @@ -19,9 +19,9 @@ class ConstructorInjection public $overloadedParameter; /** - * Force the injection of a specific value for the first parameter. (when using annotations). - * @Inject({"autowiredParameter"="anotherStdClass"}) + * Force the injection of a specific value for the first parameter. (when using attributes). */ + #[Inject(['autowiredParameter' => 'anotherStdClass'])] public function __construct(\stdClass $autowiredParameter, Class1 $overloadedParameter) { $this->autowiredParameter = $autowiredParameter; diff --git a/tests/IntegrationTest/Definitions/AutowireDefinition/MethodInjection.php b/tests/IntegrationTest/Definitions/AutowireDefinition/MethodInjection.php index 3d7e3b0a4..394ad3b67 100644 --- a/tests/IntegrationTest/Definitions/AutowireDefinition/MethodInjection.php +++ b/tests/IntegrationTest/Definitions/AutowireDefinition/MethodInjection.php @@ -4,7 +4,7 @@ namespace DI\Test\IntegrationTest\Definitions\AutowireDefinition; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class MethodInjection { @@ -19,9 +19,9 @@ class MethodInjection public $overloadedParameter; /** - * Force the injection of a specific value for the first parameter. (when using annotations). - * @Inject({"autowiredParameter"="anotherStdClass"}) + * Force the injection of a specific value for the first parameter (when using attributes). */ + #[Inject(['autowiredParameter' => 'anotherStdClass'])] public function setFoo(\stdClass $autowiredParameter, Class1 $overloadedParameter) { $this->autowiredParameter = $autowiredParameter; diff --git a/tests/IntegrationTest/Definitions/AutowireDefinitionTest.php b/tests/IntegrationTest/Definitions/AutowireDefinitionTest.php index 6f35f58bc..d93c4a6db 100644 --- a/tests/IntegrationTest/Definitions/AutowireDefinitionTest.php +++ b/tests/IntegrationTest/Definitions/AutowireDefinitionTest.php @@ -112,7 +112,7 @@ public function test_autowired_constructor_injection_can_be_overloaded(Container */ public function test_annotated_constructor_injection_can_be_overloaded(ContainerBuilder $builder) { - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ AutowireDefinition\ConstructorInjection::class => autowire() ->constructorParameter('overloadedParameter', get('foo')), @@ -139,7 +139,7 @@ public function test_annotated_constructor_injection_can_be_overloaded(Container */ public function test_annotated_method_injection_can_be_overloaded(ContainerBuilder $builder) { - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ AutowireDefinition\MethodInjection::class => autowire() ->methodParameter('setFoo', 'overloadedParameter', get('foo')), diff --git a/tests/IntegrationTest/Definitions/WildcardDefinitionsTest.php b/tests/IntegrationTest/Definitions/WildcardDefinitionsTest.php index 5685282f6..935213123 100644 --- a/tests/IntegrationTest/Definitions/WildcardDefinitionsTest.php +++ b/tests/IntegrationTest/Definitions/WildcardDefinitionsTest.php @@ -4,7 +4,7 @@ namespace DI\Test\IntegrationTest\Definitions; -use DI\Annotation\Inject; +use DI\Attribute\Inject; use DI\ContainerBuilder; use DI\Test\IntegrationTest\BaseContainerTest; use DI\Test\IntegrationTest\Fixtures\Implementation1; @@ -99,7 +99,7 @@ public function test_wildcards_autowire_with_dependency(ContainerBuilder $builde */ public function test_wildcards_as_dependency(ContainerBuilder $builder) { - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ 'DI\Test\IntegrationTest\*\Interface*' => \DI\create('DI\Test\IntegrationTest\*\Implementation*'), ]); @@ -113,8 +113,6 @@ public function test_wildcards_as_dependency(ContainerBuilder $builder) class WildcardDefinitionsTestFixture { - /** - * @Inject - */ + #[Inject] public Interface1 $dependency; } diff --git a/tests/IntegrationTest/ErrorMessages/Buggy2.php b/tests/IntegrationTest/ErrorMessages/Buggy2.php index c1aaf1d72..7003ca33d 100644 --- a/tests/IntegrationTest/ErrorMessages/Buggy2.php +++ b/tests/IntegrationTest/ErrorMessages/Buggy2.php @@ -4,14 +4,11 @@ namespace DI\Test\IntegrationTest\ErrorMessages; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class Buggy2 { - /** - * @Inject({"nonExistentEntry"}) - * @param $dependency - */ + #[Inject(['nonExistentEntry'])] public function __construct($dependency) { } diff --git a/tests/IntegrationTest/ErrorMessages/Buggy3.php b/tests/IntegrationTest/ErrorMessages/Buggy3.php index dbf8e8989..c2d2f9e67 100644 --- a/tests/IntegrationTest/ErrorMessages/Buggy3.php +++ b/tests/IntegrationTest/ErrorMessages/Buggy3.php @@ -4,12 +4,10 @@ namespace DI\Test\IntegrationTest\ErrorMessages; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class Buggy3 { - /** - * @Inject(name="namedDependency") - */ + #[Inject(name: 'namedDependency')] public $dependency; } diff --git a/tests/IntegrationTest/ErrorMessages/Buggy4.php b/tests/IntegrationTest/ErrorMessages/Buggy4.php index e0c992652..4c601600b 100644 --- a/tests/IntegrationTest/ErrorMessages/Buggy4.php +++ b/tests/IntegrationTest/ErrorMessages/Buggy4.php @@ -4,13 +4,11 @@ namespace DI\Test\IntegrationTest\ErrorMessages; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class Buggy4 { - /** - * @Inject({"nonExistentBean"}) - */ + #[Inject(['nonExistentBean'])] public function setDependency($dependency) { } diff --git a/tests/IntegrationTest/ErrorMessages/Buggy5.php b/tests/IntegrationTest/ErrorMessages/Buggy5.php index 9ab77cb91..f6ed30258 100644 --- a/tests/IntegrationTest/ErrorMessages/Buggy5.php +++ b/tests/IntegrationTest/ErrorMessages/Buggy5.php @@ -4,13 +4,11 @@ namespace DI\Test\IntegrationTest\ErrorMessages; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class Buggy5 { - /** - * @Inject - */ + #[Inject] public function setDependency($dependency) { $this->dependency = $dependency; diff --git a/tests/IntegrationTest/ErrorMessages/ErrorMessagesTest.php b/tests/IntegrationTest/ErrorMessages/ErrorMessagesTest.php index c21ca4462..da3dd4157 100644 --- a/tests/IntegrationTest/ErrorMessages/ErrorMessagesTest.php +++ b/tests/IntegrationTest/ErrorMessages/ErrorMessagesTest.php @@ -99,7 +99,7 @@ public function test_constructor_injection_of_non_existent_container_entry(Conta { $this->expectException(DependencyException::class); $this->expectExceptionMessage('Error while injecting dependencies into DI\Test\IntegrationTest\ErrorMessages\Buggy2: No entry or class found for \'nonExistentEntry\''); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->build()->get(Buggy2::class); } @@ -110,7 +110,7 @@ public function test_property_injection_of_non_existent_container_entry(Containe { $this->expectException(DependencyException::class); $this->expectExceptionMessage('Error while injecting in DI\Test\IntegrationTest\ErrorMessages\Buggy3::dependency. No entry or class found for \'namedDependency\''); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->build()->get(Buggy3::class); } @@ -119,9 +119,9 @@ public function test_property_injection_of_non_existent_container_entry(Containe */ public function test_setter_injection_of_non_existent_container_entry(ContainerBuilder $builder) { - $this->expectException(DependencyException::class); $this->expectExceptionMessage('Error while injecting dependencies into DI\Test\IntegrationTest\ErrorMessages\Buggy4: No entry or class found for \'nonExistentBean\''); - $builder->useAnnotations(true); + $this->expectException(DependencyException::class); + $builder->useAttributes(true); $builder->build()->get(Buggy4::class); } @@ -145,7 +145,7 @@ class = DI\Test\IntegrationTest\ErrorMessages\Buggy5 $this->expectException(InvalidDefinition::class); $this->expectExceptionMessage($message); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ Buggy5::class => autowire(), ]); diff --git a/tests/IntegrationTest/Fixtures/Class1.php b/tests/IntegrationTest/Fixtures/Class1.php index b72b2ebae..3014bd541 100644 --- a/tests/IntegrationTest/Fixtures/Class1.php +++ b/tests/IntegrationTest/Fixtures/Class1.php @@ -4,38 +4,28 @@ namespace DI\Test\IntegrationTest\Fixtures; -use DI\Annotation\Inject; -use DI\Annotation\Injectable; +use DI\Attribute\Inject; +use DI\Attribute\Injectable; /** * Fixture class. - * @Injectable */ +#[Injectable] class Class1 { - /** - * @Inject - */ + #[Inject] public Class2 $property1; - /** - * @Inject - */ + #[Inject] public Interface1 $property2; - /** - * @Inject("namedDependency") - */ + #[Inject('namedDependency')] public $property3; - /** - * @Inject(name="foo") - */ + #[Inject(name: 'foo')] public $property4; - /** - * @Inject - */ + #[Inject] public LazyDependency $property5; public $constructorParam1; @@ -67,11 +57,8 @@ public function __construct(Class2 $param1, Interface1 $param2, LazyDependency $ /** * Tests optional parameter is not overridden. - * - * @Inject - * @param Class2 $param1 - * @throws \Exception */ + #[Inject] public function method1(Class2 $param1, $optional = true) { $this->method1Param1 = $param1; @@ -83,10 +70,8 @@ public function method1(Class2 $param1, $optional = true) /** * Tests automatic resolution of parameter based on the type-hinting. - * - * @Inject - * @param Interface1 $param1 */ + #[Inject] public function method2(Interface1 $param1) { $this->method2Param1 = $param1; @@ -95,9 +80,9 @@ public function method2(Interface1 $param1) /** * Tests defining parameters. * - * @Inject({"namedDependency", "foo"}) * @param string $param1 */ + #[Inject(['namedDependency', 'foo'])] public function method3($param1, $param2) { $this->method3Param1 = $param1; @@ -106,10 +91,8 @@ public function method3($param1, $param2) /** * Tests injecting a lazy dependency. - * - * @Inject - * @param LazyDependency $param1 */ + #[Inject] public function method4(LazyDependency $param1) { $this->method4Param1 = $param1; diff --git a/tests/IntegrationTest/Fixtures/InheritanceTest/BaseClass.php b/tests/IntegrationTest/Fixtures/InheritanceTest/BaseClass.php index cbb825e43..170cb8d5c 100644 --- a/tests/IntegrationTest/Fixtures/InheritanceTest/BaseClass.php +++ b/tests/IntegrationTest/Fixtures/InheritanceTest/BaseClass.php @@ -4,16 +4,14 @@ namespace DI\Test\IntegrationTest\Fixtures\InheritanceTest; -use DI\Annotation\Inject; +use DI\Attribute\Inject; /** * Fixture class. */ abstract class BaseClass { - /** - * @Inject - */ + #[Inject] public Dependency $property1; public Dependency $property2; @@ -25,9 +23,7 @@ public function __construct(Dependency $param1) $this->property3 = $param1; } - /** - * @Inject - */ + #[Inject] public function setProperty2(Dependency $property2) { $this->property2 = $property2; diff --git a/tests/IntegrationTest/Fixtures/InheritanceTest/SubClass.php b/tests/IntegrationTest/Fixtures/InheritanceTest/SubClass.php index ebfad0543..ae30fcc2c 100644 --- a/tests/IntegrationTest/Fixtures/InheritanceTest/SubClass.php +++ b/tests/IntegrationTest/Fixtures/InheritanceTest/SubClass.php @@ -4,15 +4,13 @@ namespace DI\Test\IntegrationTest\Fixtures\InheritanceTest; -use DI\Annotation\Inject; +use DI\Attribute\Inject; /** * Fixture class. */ class SubClass extends BaseClass { - /** - * @Inject - */ + #[Inject] public Dependency $property4; } diff --git a/tests/IntegrationTest/Fixtures/Interface1.php b/tests/IntegrationTest/Fixtures/Interface1.php index 662821018..b39f2fdf9 100644 --- a/tests/IntegrationTest/Fixtures/Interface1.php +++ b/tests/IntegrationTest/Fixtures/Interface1.php @@ -4,12 +4,12 @@ namespace DI\Test\IntegrationTest\Fixtures; -use DI\Annotation\Injectable; +use DI\Attribute\Injectable; /** * Fixture interface. - * @Injectable */ +#[Injectable] interface Interface1 { } diff --git a/tests/IntegrationTest/Fixtures/LazyDependency.php b/tests/IntegrationTest/Fixtures/LazyDependency.php index 8dcb1d4c2..106acd3a7 100644 --- a/tests/IntegrationTest/Fixtures/LazyDependency.php +++ b/tests/IntegrationTest/Fixtures/LazyDependency.php @@ -4,18 +4,15 @@ namespace DI\Test\IntegrationTest\Fixtures; -use DI\Annotation\Injectable; +use DI\Attribute\Injectable; /** * Fixture class. - * @Injectable(lazy=true) */ +#[Injectable(lazy: true)] class LazyDependency { - /** - * @return bool - */ - public function getValue() + public function getValue(): bool { return true; } diff --git a/tests/IntegrationTest/InheritanceTest.php b/tests/IntegrationTest/InheritanceTest.php index c22ff75a5..a1aa84377 100644 --- a/tests/IntegrationTest/InheritanceTest.php +++ b/tests/IntegrationTest/InheritanceTest.php @@ -22,7 +22,7 @@ class InheritanceTest extends BaseContainerTest public function test_dependency_is_injected_if_injection_defined_on_parent_class_with_config(ContainerBuilder $builder) { $builder->useAutowiring(false); - $builder->useAnnotations(false); + $builder->useAttributes(false); $builder->addDefinitions([ Dependency::class => \DI\create(), BaseClass::class => \DI\create(SubClass::class) @@ -51,10 +51,10 @@ public function test_dependency_is_injected_if_injection_defined_on_parent_class * * @dataProvider provideContainer */ - public function test_dependency_is_injected_if_injection_defined_on_parent_class_with_annotations(ContainerBuilder $builder) + public function test_dependency_is_injected_if_injection_defined_on_parent_class_with_attributes(ContainerBuilder $builder) { $builder->useAutowiring(true); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ BaseClass::class => \DI\get(SubClass::class), ]); @@ -76,7 +76,7 @@ public function test_dependency_is_injected_if_injection_defined_on_parent_class public function test_dependency_is_injected_if_injection_defined_on_base_class_with_config(ContainerBuilder $builder) { $builder->useAutowiring(false); - $builder->useAnnotations(false); + $builder->useAttributes(false); $builder->addDefinitions([ Dependency::class => \DI\create(), BaseClass::class => \DI\create(SubClass::class) @@ -105,10 +105,10 @@ public function test_dependency_is_injected_if_injection_defined_on_base_class_w * * @dataProvider provideContainer */ - public function test_dependency_is_injected_if_injection_defined_on_base_class_with_annotations(ContainerBuilder $builder) + public function test_dependency_is_injected_if_injection_defined_on_base_class_with_attributes(ContainerBuilder $builder) { $builder->useAutowiring(true); - $builder->useAnnotations(true); + $builder->useAttributes(true); $builder->addDefinitions([ BaseClass::class => \DI\get(SubClass::class), ]); diff --git a/tests/IntegrationTest/Issues/Issue72/Class1.php b/tests/IntegrationTest/Issues/Issue72/Class1.php index 74afcb214..2405c56b7 100644 --- a/tests/IntegrationTest/Issues/Issue72/Class1.php +++ b/tests/IntegrationTest/Issues/Issue72/Class1.php @@ -4,15 +4,13 @@ namespace DI\Test\IntegrationTest\Issues\Issue72; -use DI\Annotation\Inject; +use DI\Attribute\Inject; class Class1 { public $arg1; - /** - * @Inject({"service1"}) - */ + #[Inject(['service1'])] public function __construct(\stdClass $arg1) { $this->arg1 = $arg1; diff --git a/tests/IntegrationTest/Issues/Issue72Test.php b/tests/IntegrationTest/Issues/Issue72Test.php index ea40ab8f6..47d3b7509 100644 --- a/tests/IntegrationTest/Issues/Issue72Test.php +++ b/tests/IntegrationTest/Issues/Issue72Test.php @@ -22,7 +22,7 @@ class Issue72Test extends BaseContainerTest public function annotationDefinitionShouldOverrideReflectionDefinition(ContainerBuilder $builder) { $builder->useAutowiring(true); - $builder->useAnnotations(true); + $builder->useAttributes(true); $container = $builder->build(); $value = new \stdClass(); @@ -42,7 +42,7 @@ public function annotationDefinitionShouldOverrideReflectionDefinition(Container public function arrayDefinitionShouldOverrideReflectionDefinition(ContainerBuilder $builder) { $builder->useAutowiring(true); - $builder->useAnnotations(false); + $builder->useAttributes(false); // Override to 'service2' in the definition file $builder->addDefinitions(__DIR__ . '/Issue72/definitions.php'); @@ -62,7 +62,7 @@ public function arrayDefinitionShouldOverrideReflectionDefinition(ContainerBuild public function arrayDefinitionShouldOverrideAnnotationDefinition(ContainerBuilder $builder) { $builder->useAutowiring(false); - $builder->useAnnotations(true); + $builder->useAttributes(true); // Override 'service1' to 'service2' in the definition file $builder->addDefinitions(__DIR__ . '/Issue72/definitions.php'); @@ -82,7 +82,7 @@ public function arrayDefinitionShouldOverrideAnnotationDefinition(ContainerBuild public function arrayDefinitionShouldOverrideAnotherArrayDefinition(ContainerBuilder $builder) { $builder->useAutowiring(false); - $builder->useAnnotations(false); + $builder->useAttributes(false); // Override 'service1' to 'service2' in the definition file $builder->addDefinitions(__DIR__ . '/Issue72/definitions.php'); @@ -109,7 +109,7 @@ public function phpDefinitionShouldOverrideArrayDefinition(ContainerBuilder $bui } $builder->useAutowiring(false); - $builder->useAnnotations(false); + $builder->useAttributes(false); $builder->addDefinitions(__DIR__ . '/Issue72/definitions.php'); $container = $builder->build(); diff --git a/tests/PerformanceTest/autowire.php b/tests/PerformanceTest/autowire.php index ec2171f52..97c2be1fd 100644 --- a/tests/PerformanceTest/autowire.php +++ b/tests/PerformanceTest/autowire.php @@ -10,7 +10,7 @@ $builder = new ContainerBuilder(); $builder->useAutowiring(true); -$builder->useAnnotations(false); +$builder->useAttributes(false); $builder->addDefinitions(__DIR__ . '/get/config.php'); $builder->enableCompilation(__DIR__ . '/tmp', 'Get'); $container = $builder->build(); diff --git a/tests/PerformanceTest/call.php b/tests/PerformanceTest/call.php index 8e6722d63..017cd7946 100644 --- a/tests/PerformanceTest/call.php +++ b/tests/PerformanceTest/call.php @@ -7,7 +7,7 @@ $builder = new ContainerBuilder(); $builder->useAutowiring(true); -$builder->useAnnotations(false); +$builder->useAttributes(false); $builder->enableCompilation(__DIR__ . '/tmp', 'Call'); $builder->addDefinitions([ 'link' => 'Hello', diff --git a/tests/PerformanceTest/factory.php b/tests/PerformanceTest/factory.php index 2f3145457..c1ea296f8 100644 --- a/tests/PerformanceTest/factory.php +++ b/tests/PerformanceTest/factory.php @@ -15,7 +15,7 @@ class Bar $builder = new ContainerBuilder(); $builder->useAutowiring(false); -$builder->useAnnotations(false); +$builder->useAttributes(false); $builder->enableCompilation(__DIR__ . '/tmp', 'Factory'); $builder->addDefinitions(__DIR__ . '/factory/config.php'); diff --git a/tests/PerformanceTest/get-cache.php b/tests/PerformanceTest/get-cache.php index b993766d1..2ddf15034 100644 --- a/tests/PerformanceTest/get-cache.php +++ b/tests/PerformanceTest/get-cache.php @@ -19,7 +19,7 @@ for ($i = 0; $i < 100; $i++) { $builder = new ContainerBuilder(); $builder->useAutowiring(true); - $builder->useAnnotations(false); + $builder->useAttributes(false); $builder->addDefinitions(__DIR__ . '/get/config.php'); if ($compile) { $builder->enableCompilation(__DIR__ . '/tmp/', "Container$i"); diff --git a/tests/PerformanceTest/get-object.php b/tests/PerformanceTest/get-object.php index fd523af57..aa6922e3f 100644 --- a/tests/PerformanceTest/get-object.php +++ b/tests/PerformanceTest/get-object.php @@ -8,7 +8,7 @@ $builder = new ContainerBuilder(); $builder->useAutowiring(true); -$builder->useAnnotations(false); +$builder->useAttributes(false); $builder->addDefinitions(__DIR__ . '/get-object/config.php'); $builder->enableCompilation(__DIR__ . '/tmp', 'GetObject'); $container = $builder->build(); diff --git a/tests/PerformanceTest/get.php b/tests/PerformanceTest/get.php index ec2171f52..97c2be1fd 100644 --- a/tests/PerformanceTest/get.php +++ b/tests/PerformanceTest/get.php @@ -10,7 +10,7 @@ $builder = new ContainerBuilder(); $builder->useAutowiring(true); -$builder->useAnnotations(false); +$builder->useAttributes(false); $builder->addDefinitions(__DIR__ . '/get/config.php'); $builder->enableCompilation(__DIR__ . '/tmp', 'Get'); $container = $builder->build(); diff --git a/tests/UnitTest/Annotation/Fixtures/Dependency.php b/tests/UnitTest/Annotation/Fixtures/Dependency.php deleted file mode 100644 index 48120f42c..000000000 --- a/tests/UnitTest/Annotation/Fixtures/Dependency.php +++ /dev/null @@ -1,9 +0,0 @@ -annotationReader = $definitionReader->getAnnotationReader(); - $this->reflectionClass = new ReflectionClass(InjectFixture::class); - } - - public function testProperty1() - { - $property = $this->reflectionClass->getProperty('property1'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getPropertyAnnotation($property, Inject::class); - - $this->assertInstanceOf(Inject::class, $annotation); - $this->assertEquals('foo', $annotation->getName()); - } - - public function testProperty2() - { - $property = $this->reflectionClass->getProperty('property2'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getPropertyAnnotation($property, Inject::class); - - $this->assertInstanceOf(Inject::class, $annotation); - $this->assertNull($annotation->getName()); - } - - public function testProperty3() - { - $property = $this->reflectionClass->getProperty('property3'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getPropertyAnnotation($property, Inject::class); - - $this->assertInstanceOf(Inject::class, $annotation); - $this->assertEquals('foo', $annotation->getName()); - } - - public function testMethod1() - { - $method = $this->reflectionClass->getMethod('method1'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getMethodAnnotation($method, Inject::class); - - $this->assertInstanceOf(Inject::class, $annotation); - $this->assertEmpty($annotation->getParameters()); - } - - public function testMethod2() - { - $method = $this->reflectionClass->getMethod('method2'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getMethodAnnotation($method, Inject::class); - $parameters = $annotation->getParameters(); - - $this->assertInstanceOf(Inject::class, $annotation); - $this->assertCount(2, $parameters); - $this->assertEquals('foo', $parameters[0]); - $this->assertEquals('bar', $parameters[1]); - } - - public function testMethod3() - { - $method = $this->reflectionClass->getMethod('method3'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getMethodAnnotation($method, Inject::class); - $parameters = $annotation->getParameters(); - - $this->assertInstanceOf(Inject::class, $annotation); - $this->assertCount(1, $parameters); - - $this->assertArrayHasKey('str1', $parameters); - $this->assertEquals('foo', $parameters['str1']); - } - - public function testInvalidAnnotation() - { - $this->expectException(InvalidAnnotation::class); - $this->expectExceptionMessage('@Inject({"param" = "value"}) expects "value" to be a string, [] given.'); - $method = $this->reflectionClass->getMethod('method4'); - $this->annotationReader->getMethodAnnotation($method, Inject::class); - } - - /** - * Inject annotation should work even if not imported. - */ - public function testNonImportedAnnotation() - { - $class = new ReflectionClass(NonImportedInjectFixture::class); - $property = $class->getProperty('property1'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getPropertyAnnotation($property, Inject::class); - - $this->assertInstanceOf(Inject::class, $annotation); - } - - /** - * Inject annotation should work even if there are other weird annotations in the file. - */ - public function testMixedAnnotations() - { - $class = new ReflectionClass(MixedAnnotationsFixture::class); - $property = $class->getProperty('property1'); - /** @var $annotation Inject */ - $annotation = $this->annotationReader->getPropertyAnnotation($property, Inject::class); - - $this->assertInstanceOf(Inject::class, $annotation); - } -} diff --git a/tests/UnitTest/Annotation/InjectableTest.php b/tests/UnitTest/Annotation/InjectableTest.php deleted file mode 100644 index 1c23efc9d..000000000 --- a/tests/UnitTest/Annotation/InjectableTest.php +++ /dev/null @@ -1,52 +0,0 @@ -annotationReader = $definitionReader->getAnnotationReader(); - } - - public function testEmptyAnnotation() - { - $class = new ReflectionClass(Injectable1::class); - /** @var $annotation Injectable */ - $annotation = $this->annotationReader->getClassAnnotation($class, Injectable::class); - - $this->assertInstanceOf(Injectable::class, $annotation); - $this->assertNull($annotation->isLazy()); - } - - public function testLazy() - { - $class = new ReflectionClass(Injectable2::class); - /** @var $annotation Injectable */ - $annotation = $this->annotationReader->getClassAnnotation($class, Injectable::class); - - $this->assertInstanceOf(Injectable::class, $annotation); - $this->assertTrue($annotation->isLazy()); - } -} diff --git a/tests/UnitTest/Attributes/InjectTest.php b/tests/UnitTest/Attributes/InjectTest.php index a2a28e6ce..3deceef23 100644 --- a/tests/UnitTest/Attributes/InjectTest.php +++ b/tests/UnitTest/Attributes/InjectTest.php @@ -8,7 +8,7 @@ use DI\Test\UnitTest\Attributes\Fixtures\InjectFixture; use PHPUnit\Framework\TestCase; use ReflectionClass; -use DI\Definition\Exception\InvalidAnnotation; +use DI\Definition\Exception\InvalidAttribute; /** * Inject annotation test class. @@ -95,7 +95,7 @@ public function testMethod3() public function testInvalidAnnotation() { - $this->expectException(InvalidAnnotation::class); + $this->expectException(InvalidAttribute::class); $this->expectExceptionMessage("#[Inject(['param' => 'value'])] expects \"value\" to be a string, [] given."); $method = $this->reflectionClass->getMethod('method4'); $method->getAttributes(Inject::class)[0]->newInstance(); diff --git a/tests/UnitTest/ContainerBuilderTest.php b/tests/UnitTest/ContainerBuilderTest.php index 816bb869a..1a863cb76 100644 --- a/tests/UnitTest/ContainerBuilderTest.php +++ b/tests/UnitTest/ContainerBuilderTest.php @@ -207,10 +207,10 @@ public function should_have_a_fluent_interface() { $builder = new ContainerBuilder(); - $result = $builder->useAnnotations(false); + $result = $builder->useAttributes(false); $this->assertSame($builder, $result); - $result = $builder->useAnnotations(true); + $result = $builder->useAttributes(true); $this->assertSame($builder, $result); $result = $builder->useAutowiring(false); diff --git a/tests/UnitTest/Definition/Source/AnnotationBasedAutowiringTest.php b/tests/UnitTest/Definition/Source/AttributeBasedAutowiringTest.php similarity index 72% rename from tests/UnitTest/Definition/Source/AnnotationBasedAutowiringTest.php rename to tests/UnitTest/Definition/Source/AttributeBasedAutowiringTest.php index 61a1aefdb..0204e2ec6 100644 --- a/tests/UnitTest/Definition/Source/AnnotationBasedAutowiringTest.php +++ b/tests/UnitTest/Definition/Source/AttributeBasedAutowiringTest.php @@ -4,13 +4,13 @@ namespace DI\Test\UnitTest\Definition\Source; -use DI\Definition\Reference; use DI\Definition\Definition; +use DI\Definition\Exception\InvalidAttribute; use DI\Definition\ObjectDefinition; use DI\Definition\ObjectDefinition\MethodInjection; use DI\Definition\ObjectDefinition\PropertyInjection; -use DI\Definition\Source\AnnotationBasedAutowiring; -use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture; +use DI\Definition\Reference; +use DI\Definition\Source\AttributeBasedAutowiring; use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture2; use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture3; use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture4; @@ -19,56 +19,56 @@ use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixtureScalarTypedProperty; use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixtureTypedProperties; use DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationInjectableFixture; +use DI\Test\UnitTest\Definition\Source\Fixtures\AttributeFixture; use PHPUnit\Framework\TestCase; -use DI\Definition\Exception\InvalidAnnotation; /** - * @covers \DI\Definition\Source\AnnotationBasedAutowiring + * @covers \DI\Definition\Source\AttributeBasedAutowiring */ -class AnnotationBasedAutowiringTest extends TestCase +class AttributeBasedAutowiringTest extends TestCase { public function testUnknownClass() { - $this->assertNull((new AnnotationBasedAutowiring)->autowire('foo')); + $this->assertNull((new AttributeBasedAutowiring)->autowire('foo')); } public function testProperty1() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $properties = $definition->getPropertyInjections(); $this->assertInstanceOf(PropertyInjection::class, $properties['property1']); $property = $properties['property1']; - $this->assertEquals('property1', $property->getPropertyName()); + $this->assertSame('property1', $property->getPropertyName()); $this->assertEquals(new Reference('foo'), $property->getValue()); } public function testUnannotatedProperty() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertNotHasPropertyInjection($definition, 'unannotatedProperty'); } public function testStaticProperty() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertNotHasPropertyInjection($definition, 'staticProperty'); } public function testUnguessableProperty() { - $this->expectException(InvalidAnnotation::class); - $this->expectExceptionMessage('@Inject found on property DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture4::property but unable to guess what to inject, please add a type to the property'); - (new AnnotationBasedAutowiring)->autowire(AnnotationFixture4::class); + $this->expectException(InvalidAttribute::class); + $this->expectExceptionMessage('#[Inject] found on property DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture4::property but unable to guess what to inject, please add a type to the property'); + (new AttributeBasedAutowiring)->autowire(AnnotationFixture4::class); } public function testTypedProperty() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixtureTypedProperties::class); + $definition = (new AttributeBasedAutowiring)->autowire(AnnotationFixtureTypedProperties::class); $this->assertNotHasPropertyInjection($definition, 'typeAndNoInject'); $this->assertHasPropertyInjection($definition, 'typedAndInject', AnnotationFixture2::class); @@ -77,13 +77,13 @@ public function testTypedProperty() public function testScalarTypedPropertiesFail() { - $this->expectException(InvalidAnnotation::class); - (new AnnotationBasedAutowiring)->autowire(AnnotationFixtureScalarTypedProperty::class); + $this->expectException(InvalidAttribute::class); + (new AttributeBasedAutowiring)->autowire(AnnotationFixtureScalarTypedProperty::class); } public function testConstructor() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $constructorInjection = $definition->getConstructorInjection(); @@ -97,7 +97,7 @@ public function testConstructor() public function testMethod1() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $methodInjection = $this->getMethodInjection($definition, 'method1'); @@ -108,7 +108,7 @@ public function testMethod1() public function testMethod2() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $methodInjection = $this->getMethodInjection($definition, 'method2'); @@ -122,7 +122,7 @@ public function testMethod2() public function testMethod3() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $methodInjection = $this->getMethodInjection($definition, 'method3'); @@ -137,7 +137,7 @@ public function testMethod3() public function testMethod4() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $methodInjection = $this->getMethodInjection($definition, 'method4'); @@ -151,7 +151,7 @@ public function testMethod4() public function testMethod5() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertInstanceOf(Definition::class, $definition); $methodInjection = $this->getMethodInjection($definition, 'method5'); @@ -166,17 +166,14 @@ public function testMethod5() public function testUnannotatedMethod() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertNull($this->getMethodInjection($definition, 'unannotatedMethod')); } - /** - * @test - */ - public function optionalParametersShouldBeIgnored() + public function testOptionalParametersShouldBeIgnored() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $methodInjection = $this->getMethodInjection($definition, 'optionalParameter'); @@ -189,21 +186,21 @@ public function optionalParametersShouldBeIgnored() public function testStaticMethod() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AttributeFixture::class); $this->assertNull($this->getMethodInjection($definition, 'staticMethod')); } public function testInjectable() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationInjectableFixture::class); + $definition = (new AttributeBasedAutowiring)->autowire(AnnotationInjectableFixture::class); $this->assertInstanceOf(Definition::class, $definition); $this->assertTrue($definition->isLazy()); } - public function test_method_injection_with_primitive_type_causes_an_error() + public function testMethodInjectionWithPrimitiveTypeCausesAnError() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixture3::class); + $definition = (new AttributeBasedAutowiring)->autowire(AnnotationFixture3::class); $this->assertInstanceOf(Definition::class, $definition); $methodInjection = $this->getMethodInjection($definition, 'method1'); @@ -219,14 +216,14 @@ public function test_method_injection_with_primitive_type_causes_an_error() public function testFailWithTypeError() { - $this->expectException(InvalidAnnotation::class); - $this->expectExceptionMessage('@Inject found on property DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture5::property but unable to guess what to inject, the type of the property does not look like a valid class or interface name'); - (new AnnotationBasedAutowiring)->autowire(AnnotationFixture5::class); + $this->expectException(InvalidAttribute::class); + $this->expectExceptionMessage('#[Inject] found on property DI\Test\UnitTest\Definition\Source\Fixtures\AnnotationFixture5::property but unable to guess what to inject, the type of the property does not look like a valid class or interface name'); + (new AttributeBasedAutowiring)->autowire(AnnotationFixture5::class); } public function testMergedWithParentDefinition() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixtureChild::class); + $definition = (new AttributeBasedAutowiring)->autowire(AnnotationFixtureChild::class); $this->assertHasPropertyInjection($definition, 'propertyChild'); $this->assertNotNull($this->getMethodInjection($definition, 'methodChild')); @@ -241,11 +238,11 @@ public function testMergedWithParentDefinition() */ public function testReadParentPrivateProperties() { - $definition = (new AnnotationBasedAutowiring)->autowire(AnnotationFixtureChild::class); + $definition = (new AttributeBasedAutowiring)->autowire(AnnotationFixtureChild::class); $this->assertHasPropertyInjection($definition, 'propertyParentPrivate'); } - private function getMethodInjection(ObjectDefinition $definition, $name): ?MethodInjection + private function getMethodInjection(ObjectDefinition $definition, $name) : ?MethodInjection { $methodInjections = $definition->getMethodInjections(); foreach ($methodInjections as $methodInjection) { @@ -262,10 +259,9 @@ private function assertHasPropertyInjection(ObjectDefinition $definition, $prope $propertyInjections = $definition->getPropertyInjections(); foreach ($propertyInjections as $propertyInjection) { if ($propertyInjection->getPropertyName() === $propertyName) { - if ($expectedType !== null) { $this->assertInstanceOf(Reference::class, $propertyInjection->getValue()); - $this->assertEquals( + $this->assertSame( $expectedType, $propertyInjection->getValue()->getTargetEntryName(), 'Property injected with the right type' diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture3.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture3.php index 437c3bef9..90d0a965e 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture3.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture3.php @@ -4,11 +4,11 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; +use DI\Attribute\Inject; + class AnnotationFixture3 { - /** - * @Inject - */ + #[Inject] public function method1(AnnotationFixture2 $param1, bool $param2) { } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture4.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture4.php index f51d9b008..5940ee7c5 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture4.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture4.php @@ -4,10 +4,10 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; +use DI\Attribute\Inject; + class AnnotationFixture4 { - /** - * @Inject - */ + #[Inject] public $property; } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture5.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture5.php index 64d72a862..0d443e238 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture5.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture5.php @@ -4,11 +4,11 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; +use DI\Attribute\Inject; + class AnnotationFixture5 { - /** - * @Inject - */ + #[Inject] public foobar $property; public function __construct(foobar $foo) diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureChild.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureChild.php index b0a17e097..3d67cf021 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureChild.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureChild.php @@ -4,21 +4,17 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; -use DI\Annotation\Inject; +use DI\Attribute\Inject; /** * Used to check that child classes also have the injections of the parent classes. */ class AnnotationFixtureChild extends AnnotationFixtureParent { - /** - * @Inject("foo") - */ + #[Inject('foo')] protected $propertyChild; - /** - * @Inject - */ + #[Inject] public function methodChild() { } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureParent.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureParent.php index a3f183a7a..a261a9366 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureParent.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureParent.php @@ -4,26 +4,20 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; -use DI\Annotation\Inject; +use DI\Attribute\Inject; /** * Used to check that child classes also have the injections of the parent classes. */ class AnnotationFixtureParent { - /** - * @Inject("foo") - */ + #[Inject('foo')] protected $propertyParent; - /** - * @Inject("foo") - */ + #[Inject('foo')] private $propertyParentPrivate; - /** - * @Inject - */ + #[Inject] public function methodParent() { } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureScalarTypedProperty.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureScalarTypedProperty.php index 7bf7f9dc8..6e64be460 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureScalarTypedProperty.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureScalarTypedProperty.php @@ -4,10 +4,10 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; +use DI\Attribute\Inject; + class AnnotationFixtureScalarTypedProperty { - /** - * @Inject - */ + #[Inject] protected int $scalarTypeAndInject; } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureTypedProperties.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureTypedProperties.php index 8bde283fe..443d5f4a3 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureTypedProperties.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixtureTypedProperties.php @@ -4,17 +4,15 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; +use DI\Attribute\Inject; + class AnnotationFixtureTypedProperties { protected AnnotationFixture2 $typedButNoInject; - /** - * @Inject - */ + #[Inject] protected AnnotationFixture2 $typedAndInject; - /** - * @Inject("name") - */ + #[Inject('name')] protected AnnotationFixture2 $typedAndNamed; } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationInjectableFixture.php b/tests/UnitTest/Definition/Source/Fixtures/AnnotationInjectableFixture.php index 19f1541a2..607dfbebd 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationInjectableFixture.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AnnotationInjectableFixture.php @@ -4,9 +4,9 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; -/** - * @Injectable(lazy=true) - */ +use DI\Attribute\Injectable; + +#[Injectable(lazy: true)] class AnnotationInjectableFixture { } diff --git a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture.php b/tests/UnitTest/Definition/Source/Fixtures/AttributeFixture.php similarity index 67% rename from tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture.php rename to tests/UnitTest/Definition/Source/Fixtures/AttributeFixture.php index 0ae309373..f768e2a87 100644 --- a/tests/UnitTest/Definition/Source/Fixtures/AnnotationFixture.php +++ b/tests/UnitTest/Definition/Source/Fixtures/AttributeFixture.php @@ -4,76 +4,60 @@ namespace DI\Test\UnitTest\Definition\Source\Fixtures; -use DI\Annotation\Inject; +use DI\Attribute\Inject; -class AnnotationFixture +class AttributeFixture { - /** - * @Inject("foo") - */ + #[Inject('foo')] protected $property1; - /** - * @Inject - */ + #[Inject] protected AnnotationFixture2 $property2; - /** - * @Inject(name="foo") - */ + #[Inject(name: 'foo')] protected $property3; protected $unannotatedProperty; /** * Static property shouldn't be injected. - * - * @Inject("foo") */ + #[Inject('foo')] protected static $staticProperty; - /** - * @Inject({"foo", "bar"}) - */ + #[Inject(['foo', 'bar'])] public function __construct($param1, $param2) { } - /** - * @Inject - */ + #[Inject] public function method1() { } - /** - * @Inject({"foo", "bar"}) - */ + #[Inject(['foo', 'bar'])] public function method2($param1, $param2) { } - /** - * @Inject - * @param $param1 - */ + #[Inject] public function method3(AnnotationFixture2 $param1) { } /** - * @Inject({"foo", "bar"}) * @param AnnotationFixture2 $param1 * @param AnnotationFixture2 $param2 */ + #[Inject(['foo', 'bar'])] public function method4($param1, $param2) { } /** * Indexed by name, param1 not specified:. - * @Inject({"param2" = "bar"}) */ + #[Inject(['param2' => 'bar'])] public function method5($param1, $param2) { } @@ -82,16 +66,12 @@ public function unannotatedMethod() { } - /** - * @Inject({"foo"}) - */ + #[Inject(['foo'])] public function optionalParameter(\stdClass $optional1 = null, \stdClass $optional2 = null) { } - /** - * @Inject - */ + #[Inject] public static function staticMethod() { } diff --git a/tests/UnitTest/Fixtures/Class1CircularDependencies.php b/tests/UnitTest/Fixtures/Class1CircularDependencies.php index 75f77dfa1..0adad772c 100644 --- a/tests/UnitTest/Fixtures/Class1CircularDependencies.php +++ b/tests/UnitTest/Fixtures/Class1CircularDependencies.php @@ -4,13 +4,13 @@ namespace DI\Test\UnitTest\Fixtures; +use DI\Attribute\Inject; + /** * Fixture class for testing circular dependencies. */ class Class1CircularDependencies { - /** - * @Inject - */ + #[Inject] public Class2CircularDependencies $class2; } diff --git a/tests/UnitTest/Fixtures/Class2CircularDependencies.php b/tests/UnitTest/Fixtures/Class2CircularDependencies.php index c82d919a9..5e9d52bca 100644 --- a/tests/UnitTest/Fixtures/Class2CircularDependencies.php +++ b/tests/UnitTest/Fixtures/Class2CircularDependencies.php @@ -4,14 +4,13 @@ namespace DI\Test\UnitTest\Fixtures; +use DI\Attribute\Inject; + /** * Fixture class for testing circular dependencies. */ class Class2CircularDependencies { - /** - * @Inject - * @var Class1CircularDependencies - */ + #[Inject] public Class1CircularDependencies $class1; } diff --git a/tests/UnitTest/Fixtures/Singleton.php b/tests/UnitTest/Fixtures/Singleton.php index 8b6b2ff2b..ee1c50c48 100644 --- a/tests/UnitTest/Fixtures/Singleton.php +++ b/tests/UnitTest/Fixtures/Singleton.php @@ -4,11 +4,9 @@ namespace DI\Test\UnitTest\Fixtures; -use DI\Annotation\Injectable; +use DI\Attribute\Injectable; -/** - * @Injectable - */ +#[Injectable] class Singleton { }