国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

FullStackDeveloper / 2268人閱讀

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

本文翻譯自 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

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

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

首先記住這句話:

大多數時候,Dependency Injection 并不需要 Container

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

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

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

Zend FrameworkZend_Mail 庫發送郵件過程為例:

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

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

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

下面是一個寫死 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 怎么創建。創建 mailer 對象的“雜活”是嵌入在 Container 中的。
Container 通過 getMailTransport() 方法,把 Zend_Mail_Transport_Smtp 這個依賴自動注入到了 Zend_Mail 中。

細心的網友可能已經發現,這里的 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;
  }
}

現在就可以隨時更改 usernamepassword 了:

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

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

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 很容易實現,但手工維護各種亂七八糟的對象還是很麻煩。下一章我將介紹 LaravelContainer 的實現方式。

作者下一章原文中講的是 ContainerSymfony 2 中的實現,我會把它換成 Laravel

原創。 所有 Laravel 文章均已收錄至 laravel-tips 項目。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25948.html

相關文章

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

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

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

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

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

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

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

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

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

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

    haitiancoder 評論0 收藏0

發表評論

0條評論

FullStackDeveloper

|高級講師

TA的文章

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