yiisoft/definitions

The package provides definition syntax

1.0.2 2022-04-01 07:44 UTC

This package is auto-updated.

Last update: 2022-05-22 09:35:07 UTC


README

68747470733a2f2f796969736f66742e6769746875622e696f2f646f63732f696d616765732f7969695f6c6f676f2e737667

Yii Definitions


Latest Stable Version Total Downloads Build status Scrutinizer Code Quality Code Coverage Mutation testing badge static analysis type-coverage

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 7.4 or higher.

Installation

The package could be installed with composer:

composer require yiisoft/definitions --prefer-dist

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'),
        ],
    ],
]

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 as keys and 1 as values 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.

Support the project

Open Collective

Follow updates

Official website Twitter Telegram Facebook Slack