代码之家  ›  专栏  ›  技术社区  ›  Mondblut

类型3:依赖注入实际上做什么?为什么我需要以下代码?

  •  0
  • Mondblut  · 技术社区  · 7 年前

    要更好地理解TYPO3,有一个小问题:

    在我的控制器中,我有以下代码:

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

    这是关于整个依赖注入。。。假设注入从我的TCA文件中获取特定类的依赖项是否正确?或者依赖注入实际上做了什么?据我所知,只有在执行以下代码时,才会连接到MySQL数据库中的表:

     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);
    }
    

    那么依赖注入到底做了什么,为什么有必要呢?

    编辑:作为附加问题。。。下面的代码是做什么的,或者更确切地说是“为什么我需要注释块中的符号?”。

     /**
         * 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);
        }
    

    我已经在函数中定义了参数,那么为什么注释会被阻止呢?我知道这是必要的,但我一直不明白为什么。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Euli    7 年前

    依赖注入与TCA或数据库无关。它甚至不是TYPO3本身,而是TYPO3用来在运行时将类外部世界中可用的其他对象的实例注入类/对象的概念。 它基本上可以与类相比较,类的构造函数定义了它所需要的对象的参数。 所以有人可能会说 @inject 注释与以下内容没有什么不同:

    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;
        }
    }
    

    这种注入的主要内容是自动化的过程,即当TYPO3通过类的内部对象构造类的实例时,检测需要注入哪些对象 GeneralUtility::makeInstance 方法 会有一张所有人的支票 @注入 然后,在类的新生成的PHP代码中插入注释、类型3和注入方法,就像我的代码示例中的方法一样。然后,它执行类的“更新”PHP代码,并实例化类的对象,所有以 inject 将检查他们期望的参数。如果存在参数类型类的相应对象,则将收集这些对象,或者将创建这些类的实例并将其提供给注入方法,从而为您的类提供现成的对象。

        2
  •  0
  •   Sybille Peters    7 年前

    你不需要两者兼而有之。如果您提供@inject注释,它将自动为您实例化(如您的示例所示):

    /**
     * applianceRepository
     *
     * @var \Cjk\Icingaconfgen\Domain\Repository\ApplianceRepository
     * 
     * @inject
     */
     protected $applianceRepository;
    
    
     ...
     $this->applianceRepository->findAll();
    

    另一种方法是:

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

    您可能希望这样做的原因是一些人提到的性能原因。如果性能不是您的问题,您可以安全地忽略这一点,并使用@inject注释。