1. 程式人生 > >理解PHP依賴注入容器(dependency injection container)系列(三) Symfony服務容器介紹

理解PHP依賴注入容器(dependency injection container)系列(三) Symfony服務容器介紹

到現在,我們談論了一些基本概念,前兩篇中的例子對於我們理解依賴注入的實現很有幫助,現在我們將深入 Symfony 2服務容器的實現。
Symfony中的依賴注入容器是一個名叫sfServiceContainer的類來管理的

按照Symfony的設計思路,任何一個服務都可以是容器管理的對像。在上一篇介紹的Zend_Mail的例子中,就有兩個對像:mailer和mail_transport

class Container
{
  static protected $shared = array();

  protected $parameters = array();

  public
function __construct(array $parameters = array()) { $this->parameters = $parameters; } public function getMailTransport() { return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array( 'auth' => 'login', 'username' => $this->parameters['mailer.username'], 'password'
=> $this->parameters['mailer.password'], 'ssl' => 'ssl', 'port' => 465, )); } 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; } }

如果讓Container類繼承Symfony的sfServiceContainer類,可以讓程式碼稍簡潔一點

class Container extends sfServiceContainer
{
  static protected $shared = array();

  protected function getMailTransportService()
  {
    return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
      'auth'     => 'login',
      'username' => $this['mailer.username'],
      'password' => $this['mailer.password'],
      'ssl'      => 'ssl',
      'port'     => 465,
    ));
  }

  protected function getMailerService()
  {
    if (isset(self::$shared['mailer']))
    {
      return self::$shared['mailer'];
    }

    $class = $this['mailer.class'];

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

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

通過觀察:省去了建構函式以及引數配置管理的程式碼。
但這不是全部,sfServiceContainer可以給我們強大而又簡潔的介面,以下是使用介面時要注意的幾點:
1、獲取服務的方法的名字必須以Service作為字尾。通常我們約定方法的名字以get開始,以Service結尾。每個服務都有唯一的標誌,標誌一般是方法名去掉前後綴,中間以下劃線分隔。如定義了getMailTransportService()方法,那麼服務名則為mail_transport
2、方法是protected型別的,意味著你無法直接呼叫方法來獲得服務。稍後會介紹如何用容器獲取服務。
3、可以將容器以陣列訪問的方式來獲取傳遞的引數。如:$this[‘mailer.class’]
服務標誌必須是唯一,且只能由字母、數字、’_’和’.’ 組成。’.’可以當作名稱空間來使用(如mail.mailer 和 mail.transport)。

現在看看如何使用這個新的容器

require_once 'PATH/TO/sf/lib/sfServiceContainerAutoloader.php';
sfServiceContainerAutoloader::register();

$sc = new Container(array(
  'mailer.username' => 'foo',
  'mailer.password' => 'bar',
  'mailer.class'    => 'Zend_Mail',
));

$mailer = $sc->mailer;

因為Container類繼承了sfServiceContainer ,介面變得很整潔。

  • 服務通過統一介面訪問
if ($sc->hasService('mailer'))
{
  $mailer = $sc->getService('mailer');
}

$sc->setService('mailer', $mailer);
  • 更簡單的方式是,服務通過屬性的方式訪問
if (isset($sc->mailer))
{
  $mailer = $sc->mailer;
}

$sc->mailer = $mailer;
  • 引數通過統一介面訪問
if (!$sc->hasParameter('mailer_class'))
{
  $sc->setParameter('mailer_class', 'Zend_Mail');
}

echo $sc->getParameter('mailer_class');

// Override all parameters of the container
$sc->setParameters($parameters);

// Adds parameters
$sc->addParameters($parameters);
  • 引數也可以通過容器像陣列一樣訪問
if (!isset($sc['mailer.class']))
{
  $sc['mailer.class'] = 'Zend_Mail';
}

$mailerClass = $sc['mailer.class'];
  • 可以將容器看成迭代器,遍歷所有服務
foreach ($sc as $id => $service)
{
  echo sprintf("Service %s is an instance of %s.\n", $id, get_class($service));
}

如果需要管理的服務不多,儘管你還是要做大量的基礎工作並且拷貝大量的程式碼,但是不得不承認使用sfServiceContainer是很有用的。
如果要管理的服務變得越來越多,就必須有一種更好的方式來描述服務了。
這就是為什麼大多數時侯,我們不會直接使用sfServiceContainer類。僅管如此,花一些時間來講述它還是很有必要的,因為它是Symfony實現依賴注入容器的重要基石。

接下來要講到sfServiceContainerBuilder類,利用它可以輕鬆完成對一個服務的定義。

相關推薦

理解PHP依賴注入容器(dependency injection container)系列() Symfony服務容器介紹

到現在,我們談論了一些基本概念,前兩篇中的例子對於我們理解依賴注入的實現很有幫助,現在我們將深入 Symfony 2服務容器的實現。 Symfony中的依賴注入容器是一個名叫sfServiceContainer的類來管理的 按照Symfony的設計思路,

理解PHP依賴注入容器(dependency injection container)系列(一) 什麼是依賴注入

本文是PHP依賴注入容器的實現這個系列的第一章。 今天,先不談容器(container),首先用一些具體的例子來介紹依賴注入的概念,證明依賴注入這種模式可以解決哪些問題,同時能給開發人員帶來哪些好處。 如果你已經知道了依賴注入的概念,你可以跳過這篇文章。

PHP程式設計師如何理解依賴注入容器(dependency injection container)

背景知識 傳統的思路是應用程式用到一個Foo類,就會建立Foo類並呼叫Foo類的方法,假如這個方法內需要一個Bar類,就會建立Bar類並呼叫Bar類的方法,而這個方法內需要一個Bim類,就會建立Bim類,接著做些其它工作。 // 程式碼【1】 class Bim {

依賴注入模式(Dependency Injection)

1、模式定義 依賴注入(Dependency Injection)是控制反轉(Inversion of Control)的一種實現方式。 我們先來看看什麼是控制反轉。 當呼叫者需要被呼叫者的協助時,在傳統的程式設計過程中,通常由呼叫者來建立被呼叫者的例項,但在這裡,建立被呼叫者的工作不再由呼叫者來完成

清晰架構(Clean Architecture)的Go微服務: 依賴注入Dependency Injection

在清晰架構(Clean Architecture)中,應用程式的每一層(用例,資料服務和域模型)僅依賴於其他層的介面而不是具體型別。 在執行時,程式容器¹負責建立具體型別並將它們注入到每個函式中,它使用的技術稱為依賴注入²。 以下是要求。 容器包的依賴關係: 容器包是唯一依賴於具體型別和許多外部庫的包,因為

PHP依賴注入、控制反轉

要想理解 PHP 依賴注入 和 控制反轉 兩個概念,就必須搞清楚如下的兩個問題: DI —— Dependency Injection 依賴注入 IoC —— Inversion of Control 控制反轉 什麼

spring依賴注入(Depondency Injection

(1)lookup-method <bean id="engine" class="pojo.Engine"></bean> <bean id="car" abstrac

PHP 依賴注入,從此不再考慮載入順序

說這個話題之前先講一個比較高階的思想--'依賴倒置原則' "依賴倒置是一種軟體設計思想,在傳統軟體中,上層程式碼依賴於下層程式碼,當下層程式碼有所改動時,上層程式碼也要相應進行改動,因此維護成本較高。而依賴倒置原則的思想是,上層不應該依賴下層,應依賴介面。意為上層程式碼定義介面,下層程式碼實現該

30行程式碼讓你理解angular依賴注入:angular 依賴注入原理

依賴注入(Dependency Injection,簡稱DI)是像C#,java等典型的面嚮物件語言框架設計原則控制反轉的一種典型的一種實現方式,angular把它引入到js中,介紹angular依賴注入的使用方式的文章很多, angular官方的文件,也有很詳細的說明。但介紹原理的較少,angular程式碼

深入理解Angular依賴注入

AngularJS依賴注入非常有用,並且是建立可測試元件的關鍵。本文解釋了AngularJS依賴注入如何工作的。 The Provider ($provide) $provide負責告訴Angular如何建立新的可注入的事物,即服務。服務是被pr

Docker教程系列:Docker容器操作

主機 linu 指定 font htm start 操作 ipad 重復 1查看容器 l 查看正在運行容器: docker ps l 查看所有的容器(啟動過的歷史容器): docker ps –a l 查看最後一次運行的容器:

理解依賴注入(Dependency Injection)

我們通過一個示例來解釋為什麼使用使用者服務定位器和依賴注入。首先,假設我們正在開發一個元件,叫SomeComponent。它執行的內容現在還不重要,我們的元件需要依賴資料庫的連線。 在下面第一個例子中,資料庫的連線是在元件內部建立的。這種方法是不實用的;事實上這

PHP規範PSR11(依賴注入容器介面)介紹

本文件描述了依賴注入容器的通用介面。 ContainerInterface設定的目標是標準化框架和庫如何使用容器來獲取物件和引數(在本文件的其餘部分中稱為條目)。 本文件中的關鍵詞“必須”,“必須”,“必需”,“應該”,“不應該”,“應該”,“不應該”,“推薦”,“可以”和“可選”按照RFC

[PHP] 理解依賴注入

兩個類有依賴關係的時候 使用者通過建構函式引數,方法或屬性等方式將具體元件,傳給自己 $storage=new Storge(); //建構函式注入 class User{ public function __construct($storage){ $this->

簡明依賴注入(Dependency Injection)

前言 這是因特奈特上面不知道第幾萬篇講依賴注入(Dependency Injection)的文章,但是說明白的卻寥寥無幾,這篇文章嘗試控制字數同時不做大多數。 首先,依賴注入的是一件很簡單的事情。 為什麼需要依賴注入 然後,假設我們有一個汽車Car,一個引擎介面Engine,兩個引擎具體實現Level

Spring4 -03 -Dependency Injection (依賴注入) : 程式碼體現/配置xml/測試

DI:中文名稱:依賴注入 英文名稱((Dependency Injection) DI 是什麼?     3.1 DI 和IoC 是一樣的,差不多一樣的技術和模板!     3.2 當一個類(A)中需要依賴另一個類(B)物件時,把 B&n

關於php依賴注入(DI)和控制反轉(IOC)的理解

一、什麼是依賴注入和控制反轉 1.依賴注入(DI)— Dependecy Injection 為了更方便的理解,我們把依賴注入分開理解,首先什麼是依賴?顧名思義,依賴就是各元件之間的一種關係。一般來說,在面向物件程式設計中,我們在類A中 使用到了 類B的例項,我們就可以說

深入理解spring容器中的控制反轉(IOC)和依賴注入(DI)

首先在開篇之前我們一定一定要明確的就是:DI和IOC並不是兩個概念,DI是IOC思想在應用上的具體例子。 什麼是控制反轉(IOC)? “控制”就是指一件事物對另一件事物進行一種管理,而另一件事物處在一件事物的管理之下,這就叫控制。 在面向物件程式設計的時候,每一個程式的

php 簡單理解依賴注入和自動載入

       因為在學習tp5框架,經常看到一種寫法__construct(Request $request){$this->request=$request}的寫法,不知道這是什麼意思,後來百度了一下,這個叫做依賴注入,具體的含義找了很多文章來看,有了一些比較

理解php中的依賴注入

<?php class Test1 { function say() { echo 'hello <br>'; } } class Test2 {