簡體   English   中英

依賴注入:DIY容器還是框架?

[英]Dependency Injection : DIY Container or Framework?

在過去的幾天里,我一直在大量閱讀有關依賴項注入的文章,並且一直在使用Aura.DI來研究IoC原理。 在實現此模式時,我遇到了一些常見的問題,但是在某些細節上我還是不太確定。

如果我想將記錄器(例如Monolog)注入到控制器類中(只是一個簡單的例子),我想使用類名作為記錄通道(基本上是new Logger('somecontroller') )。告訴,這意味着要為每個班級手動定義“注入”,我是否認為正確?

這個:

$controller = new PageController(new Logger('PageController'));

在Aura.DI中,將是:

$di->params['PageController'] = [
    'logger' => $di->lazyNew('Logger', ['name' => 'PageController'])
];

但是我必須為每個我想要不同的日志記錄通道的控制器執行此操作? 我聽說您可以在此處使用“抽象工廠模式”,但是我不確定這將如何工作? (我了解Factory模式,但從未遇到過對我有幫助的情況。AbstractFactory模式對我來說是新的)

我知道我可以編寫一個簡單的方法來遍歷控制器數組,並以較不冗長的方式執行此操作,但是這樣做確實有點不妥。

在reddit上也看到了這篇文章,並認為這很有道理。 如果無論如何我都必須手動配置所有這些依賴項,為什么不僅僅使我的配置成為實際的實現呢? 當依賴關系樹變得更大時,這可能會崩潰嗎? 我認為值得問一下人們的意見是什么。

編輯:只是模擬了一個 DIY方法如何工作的示例 ,實際上似乎還不錯...想法? (可能應該將其中的許多方法設為私有,但您會明白這一點)。

您可以就我的任何/所有問題闡明的任何觀點,將不勝感激。

您可以通過幾種不同的方式來做到這一點。

  1. LoggerFactory類插入到PageController

     class PageController { public function __construct(LoggerFactory $loggerFactory) { $this->loggerFactory = $loggerFactory; } public function someAction() { $this->loggerFactory->newInstance(__CLASS__); } } class LoggerFactory { public function newInstance($name) { return new Logger($name); } } 
  2. 使用同一Logger withName() 也許這是一件容易的事。 您注入記錄器並調用$newlogger = $this->logger->withName(__CLASS__); 並獲取克隆的新實例。

  3. 使用實例工廠

這里ExampleNeedsFactoryPageControllerExampleStructLogger

$di->params['PageController']['loggerFactory'] = $di->newFactory('Logger');

    class PageController
    {

        public function __construct(LoggerFactory $loggerFactory)
        {
            $this->loggerFactory = $loggerFactory;
        }

        public function someAction()
        {
            $logger = $this->getLogger();
        }

        public function getLogger()
        {
            $this->loggerFactory->__invoke(__CLASS__);
        }
    }

注意:在這種情況下, getLogger總是返回新的記錄器。 如果需要相同的實例,請設置記錄器。

public function getLogger()
{
    if (! $this->logger) {
        $this->logger = $this->loggerFactory->__invoke(__CLASS__);
    }

    return $this->logger;
}

您也可以將這些方法移至AbstractController類,這樣就不必每次都需要編寫要注入到控制器的內容。 (@camel_case在他的評論中確實提到了這一點)

Aura.Di還具有自動分辨率功能,可幫助您避免編寫大量配置。

希望有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM