yiisoft / definitions
The package provides definition syntax
Fund package maintenance!
Opencollective
yiisoft
Installs: 532 558
Dependents: 26
Suggesters: 0
Security: 0
Stars: 9
Watchers: 17
Forks: 3
Open Issues: 4
Requires
- php: ^8.0
- psr/container: ^1.0|^2.0
Requires (Dev)
- maglnet/composer-require-checker: ^4.2
- phpunit/phpunit: ^9.5
- rector/rector: ^0.15.2
- roave/infection-static-analysis-plugin: ^1.18
- spatie/phpunit-watcher: ^1.23
- vimeo/psalm: ^4.30|^5.6
- yiisoft/test-support: ^1.4
This package is auto-updated.
Last update: 2023-11-19 10:03:52 UTC
README
Yii Definitions
The package provides syntax constructs describing a way to create and configure a service or an object. It is used by yiisoft/di and yiisoft/factory but could be used in other PSR-11 compatible packages as well.
The following are provided:
- Definitions describing services or objects to create. This includes syntax, its validation and resolving it to objects.
- References and dynamic references to point to other definitions. These include additional utility to refer to multiple definitions at once.
Requirements
- PHP 8.0 or higher.
Installation
The package could be installed with composer:
composer require yiisoft/definitions
General usage
Definitions
Definition is describing a way to create and configure a service, an object
or return any other value. It must implement Yiisoft\Definitions\Contract\DefinitionInterface
that has a single method resolve(ContainerInterface $container)
. References are
typically stored in the container or a factory and are resolved into object
at the moment of obtaining a service instance or creating an object.
ArrayDefinition
Array definition allows describing a service or an object declaratively:
use \Yiisoft\Definitions\ArrayDefinition; $definition = ArrayDefinition::fromConfig([ 'class' => MyServiceInterface::class, '__construct()' => [42], '$propertyName' => 'value', 'setName()' => ['Alex'], ]); $object = $definition->resolve($container);
In the above:
class
contains the name of the class to be instantiated.__construct()
holds an array of constructor arguments.- The rest of the config are property values (prefixed with
$
) and method calls, postfixed with()
. They are set/called in the order they appear in the array.
CallableDefinition
Callable definition builds an object by executing a callable injecting dependencies based on types used in its signature:
use \Yiisoft\Definitions\CallableDefinition; $definition = new CallableDefinition( fn (SomeFactory $factory) => $factory->create('args') ); $object = $definition->resolve($container); // or $definition = new CallableDefinition( fn () => MyFactory::create('args') ); $object = $definition->resolve($container); // or $definition = new CallableDefinition( [MyFactory::class, 'create'] ); $object = $definition->resolve($container);
In the above we use a closure, a static call and a static method passed as array-callable. In each case we determine and pass dependencies based on the types of arguments in the callable signature.
ParameterDefinition
Parameter definition resolves an object based on information from ReflectionParameter
instance:
use \Yiisoft\Definitions\ParameterDefinition; $definition = new ParameterDefinition($reflectionParameter); $object = $definition->resolve($container);
It is mostly used internally when working with callables.
ValueDefinition
Value definition resolves value passed as is:
use \Yiisoft\Definitions\ValueDefinition; $definition = new ValueDefinition(42, 'int'); $value = $definition->resolve($container); // 42
References
References point to other definitions so when defining a definition you can use other definitions as its dependencies:
[ InterfaceA::class => ConcreteA::class, 'alternativeForA' => ConcreteB::class, MyService::class => [ '__construct()' => [ Reference::to('alternativeForA'), ], ], ]
Optional reference returns null
when there's no corresponding definition in container:
[ MyService::class => [ '__construct()' => [ // If container doesn't have definition for `EventDispatcherInterface` reference returns `null` // when resolving dependencies Reference::optional(EventDispatcherInterface::class), ], ], ]
The DynamicReference
defines a dependency to a service not defined in the container:
[ MyService::class => [ '__construct()' => [ DynamicReference::to([ 'class' => SomeClass::class, '$someProp' => 15 ]) ] ] ]
In order to pass an array of IDs as references to a property or an argument, Yiisoft\Definitions\ReferencesArray
or
Yiisoft\Definitions\DynamicReferencesArray
could be used:
//params.php return [ 'yiisoft/data-response' => [ 'contentFormatters' => [ 'text/html' => HtmlDataResponseFormatter::class, 'application/xml' => XmlDataResponseFormatter::class, 'application/json' => JsonDataResponseFormatter::class, ], ], ]; //web.php ContentNegotiator::class => [ '__construct()' => [ 'contentFormatters' => ReferencesArray::from($params['yiisoft/data-response']['contentFormatters']), ], ],
Definition storage
Definition storage could be used to hold and obtain definitions and check if a certain definition could be instantiated. Usually it is used by an implementation using the definitions:
use Yiisoft\Definitions\DefinitionStorage; $storage = new DefinitionStorage([ MyInterface::class => MyClass::class, ]); $storage->setDelegateContainer($fallbackContainer); if (!$storage->has(MyInterface::class)) { $buildStack = $storage->getBuildStack(); // ... }
In the above $buildStack
will contain a stack with definition IDs in the order the latest dependency obtained would be
built.
By default, if a class is checked in has()
and it is not explicitly defined, the storage tries to autoload it first
before failing. The storage may also work in a strict mode when everything in it should be defined explicitly:
use Yiisoft\Definitions\DefinitionStorage; $storage = new DefinitionStorage([], true); var_dump($storage->has(EngineMarkOne::class));
has()
will return false
even if EngineMarkOne
exists.
Testing
Unit testing
The package is tested with PHPUnit. To run tests:
./vendor/bin/phpunit
Mutation testing
The package tests are checked with Infection mutation framework with Infection Static Analysis Plugin. To run it:
./vendor/bin/roave-infection-static-analysis-plugin
Static analysis
The code is statically analyzed with Psalm. To run static analysis:
./vendor/bin/psalm
License
The Yii Definitions is free software. It is released under the terms of the BSD License.
Please see LICENSE
for more information.
Maintained by Yii Software.