简体   繁体   中英

TYPO3: What does dependency injection actually do and why do i need the following code?

A little question to understand TYPO3 better:

In my controller i have following code:

 /**
     * applianceRepository
     *
     * @var \Cjk\Icingaconfgen\Domain\Repository\ApplianceRepository
     * 
     * @inject
     */
    protected $applianceRepository = null;

It's about this whole dependency injection... Is it correct to assume that the injection fetches the dependencies from my TCA file for that specific class? Or what does the dependency injection actually do? From what i understand the connection to the tables in the MySQL database only happens when the following code is executed:

 public function listAction()
    {
        $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
        $apprep = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\ApplianceRepository::class);
        $appliances = $apprep->findAll();
        $this->view->assign('appliances', $appliances);
}

So what actually does the dependency injection do and why is it necessary?

Edit: As an additional question... What does the following code do or rather "Why do i need the notation in the comments block?".

 /**
     * action show
     *
     * @param \Cjk\Icingaconfgen\Domain\Model\Appliance $appliance
     * @return void
     */
    public function showAction(\Cjk\Icingaconfgen\Domain\Model\Appliance $appliance)
    {
        $this->view->assign('appliance', $appliance);
    }

I've already defined the parameter in the function, so why the comments block? I know it's necessary, but i never understood why.

Dependency injection has nothing to do with TCA or the database. It isn't even a thing of TYPO3 itself, but a concept TYPO3 uses to inject instances of other objects, available in the outside world of your class, into your class/object at runtime. It basically is comparable with a class, whichs constructor defines parameters of objects that it needs. So one could argue that the @inject annotation is nothing different then something like this:

class SomeController {
    /**
     * @var SomeClass
     * @inject
     */
    protected $someClassDependency;
}

// this is equal to

class SomeController {
    protected $someClassDependency;
    public function __construct(SomeClass $someClassDependency) {
        $this->someClassDependency = $someClassDependency;
    }
}

// and also equal to

class SomeController {
    protected $someClassDependency;
    public function injectSomeClassDependency(SomeClass $someClassDependency) {
        $this->someClassDependency = $someClassDependency;
    }
}

The main thing about this injection is the automated process that is detecting which objects need to be injected when TYPO3 constructs an instance of the class via their internal GeneralUtility::makeInstance method. There will be a check for all @inject annotations, TYPO3 then inserts inject-methods, like the one in my code example, into a newly generated PHP code of your class. It then executes that "updated" PHP code of your class and on instanciation of your class's object, all methods that start with inject will be checked for what they expect as parameters. The corresponding objects of the parameter types class will be collected if they exist or instances of the classes will be created and given to the inject-methods, thus providing ready to use objects for your class.

You don't need both. If you supply the @inject annotation, it will automatically be instantiated for you (as in your example):

/**
 * applianceRepository
 *
 * @var \Cjk\Icingaconfgen\Domain\Repository\ApplianceRepository
 * 
 * @inject
 */
 protected $applianceRepository;


 ...
 $this->applianceRepository->findAll();

An alternative is to do it this way:

/**
 * @param \Cjk\Icingaconfgen\Domain\Repository\ApplianceRepository $applianceRepository
 */ 
public function injectApplianceRepository($applianceRepository)
{
    $this->applianceRepository = $applianceRepository;
}

The reason you may want to do this are performance reasons as mentioned by several people. If performance is not an issue for you, you can safely ignore this and use the @inject annotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM