Provides some additional features into the great Nette\DI container.

v1.0.6 2024-02-13 17:52 UTC

This package is auto-updated.

Last update: 2024-04-13 17:24:48 UTC


README

Provides some additional features into the great Nette\DI container.

Requirements

Installation

The best way to install interitty/di is using Composer:

composer require interitty/di

Features

The abstract CompilerExtension class provides the standard way to work with the default parameters, expand them and validate them. It also contains the setupServiceAlias helper that simplifies the process of registering service or the alias when the service was registered before.

Literal factory

For generating more complicated entries, the Nette\PhpGenerator\Literal class can be used. The createLiteral helper factory is available for easier work.

Example: createLiteral

<?php

declare(strict_types=1);

namespace Interitty\Foo\Nette\DI;

use Interitty\DI\CompilerExtension;
use Nette\DI\Definitions\ServiceDefinition;

class FooExtension extends CompilerExtension
{
    /**
     * Foo helper
     *
     * @param ServiceDefinition $definition
     * @return void
     */
    protected function processFoo(ServiceDefinition $definition): void
    {
        $definition->addSetup('?', [$this->createLiteral('return ?;', [true])]);
    }
}

Registration helpers

Sometimes it can be useful to be able to register an extension directly in a specific order before or after another extension. For this purpose, there are auxiliary methods processRegisterAfter and processRegisterBefore that can be called in the constructor or initialization phase of a process to move the extension to the exact location.

<?php

declare(strict_types=1);

namespace Interitty\Foo\Nette\DI;

use Interitty\DI\CompilerExtension;

class FooExtension extends CompilerExtension
{
    /**
     * @inheritdoc
     */
    public function loadConfiguration(): void
    {
        parent::loadConfiguration();
        $this->processRegisterAfter('services');
    }
}

Suggestions

It also consists of the following suggestions:

  • Every config parameter should be defined as the CONFIG_* constant with his name.
  • Every config parameter should be validated in the configSchema or processConfig method.
  • Every service name should be defined as the PROVIDER_* constant.
  • Every service should be registered in the setup* method.
  • Setup methods should be called in the beforeCompile method.

Example: FooExtension

<?php

declare(strict_types=1);

namespace Interitty\Foo\Nette\DI;

use Interitty\Utils\Validators;
use Interitty\DI\CompilerExtension;

use function assert;

class FooExtension extends CompilerExtension
{

    /** All config parameter name constants */
    const CONFIG_FOO = 'foo';

    /** All available provider name constants */
    const PROVIDER_BAR = 'bar';

    /**
     * @var mixed[]
     */
    protected $defaults = [
        self::CONFIG_FOO => 'foo',
    ];

    /**
     * @inheritdoc
     */
    public function beforeCompile(): void
    {
        $this->setupFoo();
    }

    /**
     * @inheritdoc
     */
    public function processConfig(): array
    {
        $config = parent::processConfig();
        assert(Validators::check($config[self::CONFIG_FOO], 'string', self::CONFIG_FOO));
        return $config;
    }
    // <editor-fold defaultstate="collapsed" desc="Helpers">
    /**
     * Bar setup helper
     *
     * @return void
     */
    protected function setupBar(): void
    {
        if ($this->setupServiceAlias(Bar::class, self::PROVIDER_BAR) === false) {
            $builder = $this->getContainerBuilder();
            $builder->addDefinition($this->prefix(self::PROVIDER_BAR))
                ->setImplement(Bar::class)
                ->addSetup('setFoo', [$this->getConfigField(self::CONFIG_FOO));
        }
    }
}