成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel Container (容器) 概念詳解 (上)

FullStackDeveloper / 2287人閱讀

摘要:上文書,創(chuàng)建對象需要先創(chuàng)建對象。創(chuàng)建對象的雜活是嵌入在中的。對象使用來管理依賴關系非常好,但不是必須的。很容易實現(xiàn),但手工維護各種亂七八糟的對象還是很麻煩。所有文章均已收錄至項目。

本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Dependency Injection Container in PHP》 系列文章。

Part 1: What is Dependency Injection?

Part 2: Do you need a Dependency Injection Container?

Part 3: Introduction to the Symfony Service Container

Part 4: Symfony Service Container: Using a Builder to create Services

Part 5: Symfony Service Container: Using XML or YAML to describe Services

Part 6: The Need for Speed

專有名詞翻譯成中文后會變得不利于理解,后續(xù)文章中將改用括號+中文備注的形式。

上文我通過一些示例講解了 Dependency Injection ,本文將接著介紹 Dependency Injection Containers (容器) 的概念。

首先記住這句話:

大多數(shù)時候,Dependency Injection 并不需要 Container。

只有當你需要管理一大堆具有很多依賴關系的不同對象時,Container 才會非常有用(例如框架中)。

上文書,創(chuàng)建 User 對象需要先創(chuàng)建 SessionStorate 對象。這里的有個瑕疵,創(chuàng)建對象時需要提前知道它所有的依賴項:

$storage = new SessionStorage("SESSION_ID");
$user = new User($storage);

Zend FrameworkZend_Mail 庫發(fā)送郵件過程為例:

$transport = new Zend_Mail_Transport_Smtp("smtp.gmail.com", [
  "auth"     => "login",
  "username" => "foo",
  "password" => "bar",
  "ssl"      => "ssl",
  "port"     => 465,
]);

$mailer = new Zend_Mail();
$mailer->setDefaultTransport($transport);

請把這個例子看做一個大系統(tǒng)中的一小部分,因為這種簡單的例子當然沒必要用 Container 。

Dependency Injection Container 是一個“知道如何實例化和配置對象”的對象(工廠模式的升華)。為了做到這點,它需要知道構(gòu)造函數(shù)的參數(shù)、以及對象之間的關系。

下面是一個寫死 Zend_MailContainer

class Container
{
  public function getMailTransport()
  {
    return new Zend_Mail_Transport_Smtp("smtp.gmail.com", [
      "auth"     => "login",
      "username" => "foo",
      "password" => "bar",
      "ssl"      => "ssl",
      "port"     => 465,
    ]);
  }

  public function getMailer()
  {
    $mailer = new Zend_Mail();
    $mailer->setDefaultTransport($this->getMailTransport());

    return $mailer;
  }
}

這個 Container 用起來就相當簡單了:

$container = new Container();
$mailer = $container->getMailer();

我們只管向 Containermailer 對象就行,完全不用管 mailer 怎么創(chuàng)建。創(chuàng)建 mailer 對象的“雜活”是嵌入在 Container 中的。
Container 通過 getMailTransport() 方法,把 Zend_Mail_Transport_Smtp 這個依賴自動注入到了 Zend_Mail 中。

細心的網(wǎng)友可能已經(jīng)發(fā)現(xiàn),這里的 Container 把什么都寫死了。我們可以完善一下:

class Container
{
  protected $parameters = array();

  public function __construct(array $parameters = [])
  {
    $this->parameters = $parameters;
  }

  public function getMailTransport()
  {
    return new Zend_Mail_Transport_Smtp("smtp.gmail.com", [
      "auth"     => "login",
      "username" => $this->parameters["mailer.username"],
      "password" => $this->parameters["mailer.password"],
      "ssl"      => "ssl",
      "port"     => 465,
    ]);
  }

  public function getMailer()
  {
    $mailer = new Zend_Mail();
    $mailer->setDefaultTransport($this->getMailTransport());

    return $mailer;
  }
}

現(xiàn)在就可以隨時更改 usernamepassword 了:

$container = new Container([
  "mailer.username" => "foo",
  "mailer.password" => "bar",
]);
$mailer = $container->getMailer();

如果需要更改 mailer 類,把類名也當參數(shù)傳入就行:

class Container
{
  // ...

  public function getMailer()
  {
    $class = $this->parameters["mailer.class"];

    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());

    return $mailer;
  }
}

$container = new Container([
  "mailer.username" => "foo",
  "mailer.password" => "bar",
  "mailer.class"    => "Zend_Mail",
]);
$mailer = $container->getMailer();

如果想每次獲取同一個 mailer 實例,可以用 單例模式

class Container
{
  static protected $shared = [];

  // ...

  public function getMailer()
  {
    if (isset(self::$shared["mailer"]))
    {
      return self::$shared["mailer"];
    }

    $class = $this->parameters["mailer.class"];

    $mailer = new $class();
    $mailer->setDefaultTransport($this->getMailTransport());

    return self::$shared["mailer"] = $mailer;
  }
}

這就包含了 Dependency Injection Containers 的基本功能:

Container 管理對象實例化到配置的過程

對象本身不知道自己是由 Container 管理的,對 Container 一無所知。

這就是為什么 Container 能夠管理任何 PHP 對象。 對象使用 DI 來管理依賴關系非常好,但不是必須的。

Container 很容易實現(xiàn),但手工維護各種亂七八糟的對象還是很麻煩。下一章我將介紹 LaravelContainer 的實現(xiàn)方式。

作者下一章原文中講的是 ContainerSymfony 2 中的實現(xiàn),我會把它換成 Laravel。

原創(chuàng)。 所有 Laravel 文章均已收錄至 laravel-tips 項目。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25948.html

相關文章

  • Laravel Container (容器) 深入理解 (下)

    摘要:意味著依賴被注入進構(gòu)造函數(shù)或者方法如果需要復用實例,可以定義為單例可以用接口或任何名稱來代替具體類。技能重寫構(gòu)造函數(shù)參數(shù)方法允許將附加參數(shù)傳遞給構(gòu)造函數(shù)。 本文大部分翻譯自 DAVE JAMES MILLER 的 《Laravel’s Dependency Injection Container in Depth》 。 上文介紹了 Dependency Injection Contai...

    eternalshallow 評論0 收藏0
  • Laravel Dependency Injection (依賴注入) 概念詳解

    摘要:依賴注入并不限于構(gòu)造函數(shù)作為經(jīng)驗,注入最適合必須的依賴關系,比如示例中的情況注入最適合可選依賴關系,比如緩存一個對象實例。 本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Dependency Injection Container in P...

    Fundebug 評論0 收藏0
  • 深入剖析 Laravel 服務容器

    摘要:劃下重點,服務容器是用于管理類的依賴和執(zhí)行依賴注入的工具。類的實例化及其依賴的注入,完全由服務容器自動的去完成。 本文首發(fā)于 深入剖析 Laravel 服務容器,轉(zhuǎn)載請注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請求,又是如何生成響應并最終呈現(xiàn)給用戶的工作原理。 本章將帶領大...

    abson 評論0 收藏0
  • Laravel中的核心概念

    摘要:可以為服務提供者的方法設置類型提示。方法將在所有其他服務提供者均已注冊之后調(diào)用。所有服務提供者都在配置文件中注冊。可以選擇推遲服務提供者的注冊,直到真正需要注冊綁定時,這樣可以提供應用程序的性能。 本文最早發(fā)布于 Rootrl的Blog 導言 Laravel是一款先進的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...

    ddongjian0000 評論0 收藏0
  • 詳解 Laravel 中的依賴注入和 IoC

    摘要:依賴注入依賴注入一詞是由提出的術語,它是將組件注入到應用程序中的一種行為。就像說的依賴注入是敏捷架構(gòu)中關鍵元素。類依賴于,所以我們的代碼可能是這樣的創(chuàng)建一個這是一種經(jīng)典的方法,讓我們從使用構(gòu)造函數(shù)注入開始。 showImg(https://segmentfault.com/img/remote/1460000018806800); 文章轉(zhuǎn)自:https://learnku.com/la...

    haitiancoder 評論0 收藏0

發(fā)表評論

0條評論

FullStackDeveloper

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<