Di Der Dependency Injection Container

Grundsätzliches was überhaupt Dependency Injection ist: https://phptherightway.com/#dependency_injection

 Das Di vom SetaFramework unterstützt sogenanntes Autowiring. Das bedeutet, dass nicht konfiguriert werden muss welche Objekte übergeben werden, sondern das Di versucht mit Hilfe der Reflection-API selbstständig herauszufinden, welches Objekt benötigt wird.

Konfigurieren vom Di

Es ist möglich das Di komplett losgelöst von der kompletten Applikationsstruktur zu verwenden:

PHP
use com\setasign\SetaFramework\Di\Di;
use com\setasign\SetaFramework\Database\RowFactoryInterface;
use com\setasign\SetaFramework\Database\DiRowFactory;
use com\setasign\SetaFramework\Log\LogHandler;
use com\setasign\SetaFramework\Di\GlobalDi;

$di = new Di();

$di->configure(DiRowFactory::class);
$di->addAlias(RowFactoryInterface::class, DiRowFactory::class);
$di->addAlias(LogHandler::class, function (): LogHandler {
    return GlobalDi::getInstance()->get(LogHandler::class);
});

Innerhalb einer Applikation

Üblicher ist jedoch die Verwendung vom Di innerhalb einer Applikation. 

PHP
// applikationsklasse
    /** @noinspection PhpInternalEntityUsedInspection */
    public function getDi(): ApplicationDi
    {
        if ($this->di === null) {
            /** @noinspection PhpInternalEntityUsedInspection */
            $this->di = new OwnApplicationDi($this, $this->bootstrap);
        }
        return $this->di;
    }

// eigene di klasse
/**
 * You shouldn't use this class for anything (no typehints! no instanceof!).
 * Use \com\setasign\SetaFramework\Di\Di instead!
 *
 * @internal
 */
class OwnApplicationDi extends ApplicationDi
{
    protected function init(): void
    {
        parent::init();

        $this->addAlias(SomeInterface::class, DefaultImplementation::class);
    }
}

Verwendung

Grundsätzlich sollte das Di so wenig wie möglich direkt verwendet werden!
Stattdessen sollte sich auf das Autowiring verlassen werden. 

Es jedoch trotzdem möglich das Di direkt zu verwenden. Hierfür gibt es folgende Methoden:

call()

Call the callable and autowire the params.

callNewInstance()

Create a new instance of $className and autowire the params.

get()

Get an instance by class name or alias.

hasInstance()

Checks whether the di has an instance for this alias or className

DI Attributes

Ab Version 6.8.0 gibt es PHP Attribute die von dem Di beachtet werden. Die Attribute implementieren das DiAttribute-Interface. DiAttribute überschreiben komplett das Standardverhalten vom Di was injectet wird. Es gibt folgende vordefinierte Attribute im SetaFramework:

  • ApplicationConfigValue - gibt einen Wert aus der Applikations-Konfiguration aus
  • ApplicationLogger - gibt ein LoggerInterface zu dem angegebenen Kanal aus
  • GetObject - gibt ein Objekt aus dem DI zurück
  • GetObjectFromApplication - gibt ein Objekt aus einer anderen Applikation aus

Beispiele (Named Parameter nicht zwingend nötig):

PHP
<?php

function test(
    #[ApplicationConfigValue(path: 'debug', default: false)]
    bool $debug,
    #[ApplicationLogger(loggerChannel: 'blocks', ensureLogger: true)]
    LoggerInterface $logger,
    #[GetObject(className: SimpleApp::class)]
    HttpApplicationInterface $app,
    #[GetObjectFromApplication(applicationName: 'simpleApp', className: SimpleApp::class)]
    SimpleApp $simpleApp
) {
}