Die hier vorgestellten Arten von Dependency Injection setzen voraus, dass das Objekt über den ObjectManager via $objectManager->get('\ClassName') instanziert wird oder über GeneralUtility::makeInstance('\ClassName'). Andernfalls, z.B. bei Instanzierung über "new \ClassName", wird der Dependency Injection Mechanismus komplett umgangen.
Dependency Injection - Setter-Injection
class MyClass {
/**
* Object Manager
*
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
*/
protected $objectManager;
/**
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
*/
public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
$this->objectManager = $objectManager;
}
}
Dependency Injection - @inject-Annotation
class MyClass {
/**
* Object Manager
*
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
* @inject
*/
protected $objectManager;
}
Dependency Injection - Constructor-Injection
class MyClass {
/**
* Object Manager
*
* @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
*/
protected $objectManager;
/**
* @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
*/
public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
$this->objectManager = $objectManager;
}
}
Bei der Programmierung gegen Interfaces überprüft Extbase die Klassennamen. Endet dieser auf "Interface", wird der Teil abgeschnitten und Extbase sucht nach einer konkreten Implementierung des Interfaces. Falls diese vorhanden ist, wird automatisch diese Klasse instanziert.
Darüber hinaus ist es möglich, über TypoScript ein individuelles Mapping von Interfaces auf konkrete Klassen zu definieren. Dieses Mapping kann global oder auf Plugin-Basis festgelegt werden.
Interface Mapping - global
config.tx_extbase.objects {
\TYPO3\CMS\Extbase\Object\ObjectManagerInterface {
className = \TYPO3\CMS\Extbase\Object\ObjectManager
}
}
Interface Mapping - auf Plugin-Ebene
plugin.tx_myext.objects {
\TYPO3\CMS\Extbase\Object\ObjectManagerInterface {
className = \TYPO3\CMS\Extbase\Object\ObjectManager
}
}
Kommentare
Jetzt muss eine extension/Configuration/Services.yaml erzeugt werden.
Inhalt:
```
# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: true
Vendor\SomeExtension\Service\FrontendUserAuthenticationDevelopmentService: ~
Vendor\SomeExtension\Service\FrontendUserAuthenticationServiceInterface: '@Vendor\SomeExtension\Service\FrontendUserAuthenticationDevelopmentService'
```
Wenn GeneralUtility::makeInstance verwendet werden soll ist es sehr wichtig den Wert für public auf true zu setzen!
Hat mich gerade eine Stunde gekostet. Ich hoffe es hilft jemanden.
Weitere Info zur DI in TYPO3 11
https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/DependencyInjection/Index.html#autoconfigure
https://symfony.com/doc/current/service_container/autowiring.html#working-with-interfaces