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

Alex schrieb am 18.11.2021:
Für TYPO3 11 scheint das Interface Mapping per TypoScript nicht mehr zu funktionieren.
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