Zend Framework - 服務管理器



Zend Framework 包含一個強大的服務定位器模式實現,稱為zend-servicemanager。Zend Framework 廣泛地將其用於所有功能。服務管理器為 Zend Framework 提供了高階抽象。它還可以很好地與 Zend Framework 的所有其他元件整合。

安裝服務管理器

可以使用composer工具安裝服務管理器元件。

composer require zendframework/zend-servicemanager

示例

首先,所有服務都需要註冊到服務管理器中。服務註冊到伺服器管理器系統後,可以隨時以最小的努力訪問它。服務管理器提供了許多註冊服務的選項。一個簡單的示例如下:

use Zend\ServiceManager\ServiceManager; 
use Zend\ServiceManager\Factory\InvokableFactory; 
use stdClass;  
$serviceManager = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class,], 
]);

上述程式碼使用Factory選項將stdClass註冊到系統中。現在,我們可以使用服務管理器的get()方法隨時獲取stdClass的例項,如下所示。

use Zend\ServiceManager\ServiceManager;  
$object = $serviceManager->get(stdClass::class);

get() 方法共享檢索到的物件,因此,多次呼叫 get() 方法返回的物件是同一個例項。為了每次獲取不同的例項,服務管理器提供了另一個方法,即build()方法。

use Zend\ServiceManager\ServiceManager;  
$a = $serviceManager->build(stdClass::class); 
$b = $serviceManager->build(stdClass::class);

服務管理器註冊

服務管理器提供了一組註冊元件的方法。一些最重要的方法如下:

  • 工廠方法
  • 抽象工廠方法
  • 初始化方法
  • 委託工廠方法

我們將在接下來的章節中詳細討論這些方法。

工廠方法

工廠基本上是任何可呼叫物件或任何實現FactoryInterface (Zend\ServiceManager\Factory\FactoryInterface) 的類。

FactoryInterface 只有一個方法:

public function __invoke(ContainerInterface $container, $requestedName, array 
   $options = null)

FactoryInterface 的引數詳細資訊如下:

  • container (ContainerInterface) - 它是 ServiceManager 的基本介面。它提供了一個獲取其他服務的選項。

  • requestedName - 它是服務名稱。

  • options - 它提供了服務所需的附加選項。

讓我們建立一個簡單的實現 FactoryInterface 的類,看看如何註冊該類。

類 Test - 要檢索的物件

use stdClass;  
class Test { 
   public function __construct(stdClass $sc) { 
      // use $sc 
   } 
} 

Test 類依賴於 stdClass。

類 TestFactory - 初始化 Test 物件的類

class TestFactory implements FactoryInterface { 
   public function __invoke(ContainerInterface $container, $requestedName, 
      array $options = null) { 
      $dep = $container->get(stdClass::class); 
      return new Test($dep); 
   } 
}

TestFactory 使用容器檢索 stdClass,建立 Test 類的例項並返回它。

Zend Framework 的註冊和使用

現在讓我們瞭解如何註冊和使用 Zend Framework。

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class, 
      Test::class => TestFactory::class] 
]); 
$test = $sc->get(Test::class);

服務管理器提供了一個名為InvokableFactory的特殊工廠來檢索任何沒有依賴項的類。例如,由於 stdClass 不依賴於任何其他類,因此可以使用 InvokableFactory 配置stdClass

serviceManager $sc = new ServiceManager([ 
   'factories' => [stdClass::class => InvokableFactory::class] 
]);  
$stdC = $sc->get(stdClass::class); 

另一種無需實現FactoryInterface或使用InvokableFactory即可檢索物件的方法是使用如下所示的內聯方法。

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class, 
      Test::class => function(ContainerInterface $container, $requestedName) { 
         $dep = $container->get(stdClass::class); 
         return new Test($dep); 
      }, 
   ], 
]);

抽象工廠方法

有時,我們可能需要建立的物件只有在執行時才知道。這種情況可以使用AbstractFactoryInterface來處理,它派生自 FactoryInterface。

AbstractFactoryInterface 定義了一個方法來檢查是否可以在請求的例項中建立物件。如果可以建立物件,它將使用 FactoryInterface 的__invoke方法建立物件並返回它。

AbstractFactoryInterface 的簽名如下:

public function canCreate(ContainerInterface $container, $requestedName) 

初始化方法

初始化方法是一種特殊的選項,用於為已建立的服務注入額外的依賴項。它實現了InitializerInterface,並且唯一可用方法的簽名如下:

public function(ContainerInterface $container, $instance)  
function(ContainerInterface $container, $instance) { 
   if (! $instance instanceof EventManagerAwareInterface) { 
      return; 
   } 
   $instance->setEventManager($container->get(EventManager::class)); 
} 

在上面的示例中,該方法檢查例項是否為 EventManagerAwareInterface 型別。如果它是EventManagerAwareInterface型別,則設定事件管理器物件,否則不設定。由於該方法可能會也可能不會設定依賴項,因此它不可靠並會產生許多執行時問題。

委託工廠方法

Zend Framework 透過DelegatorFactoryInterface支援委託模式。它可以用來裝飾服務。

此函式的簽名如下:

public function __invoke(ContainerInterface $container, 
   $name, callable $callback, array $options = null 
); 

這裡,$callback負責裝飾服務例項。

延遲服務

延遲服務是在建立時不會完全初始化的服務之一。它們只是被引用,只有在真正需要時才會被初始化。最好的例子之一是資料庫連線,它可能並非在所有地方都需要。它是一種昂貴的資源,並且建立過程也很耗時。Zend Framework 提供了派生自DelegatorFactoryInterfaceLazyServiceFactory,它可以藉助Delegator概念和一個第三方代理管理器(稱為ocramius 代理管理器)來生成延遲服務。

外掛管理器

外掛管理器擴充套件了服務管理器,並提供附加功能,例如例項驗證。Zend Framework 廣泛使用外掛管理器。

例如,所有驗證服務都位於ValidationPluginManager下。

配置選項

服務管理器提供了一些選項來擴充套件服務管理器的功能。它們是shared、shared_by_defaultaliases。正如我們前面討論的,檢索到的物件預設情況下在請求的物件之間共享,我們可以使用build()方法獲取不同的物件。我們還可以使用shared選項來指定要共享的服務。shared_by_defaultshared功能相同,只是它適用於所有服務。

$serviceManager = new ServiceManager([ 
   'factories' => [ 
      stdClass::class => InvokableFactory::class 
   ], 
   'shared' => [ 
      stdClass::class => false // will not be shared 
   ], 
   'shared_by_default' => false, // will not be shared and applies to all service 
]);

aliases選項可用於為註冊的服務提供替代名稱。這既有優點也有缺點。從好的方面來說,我們可以為服務提供簡短的替代名稱。但與此同時,名稱可能會脫離上下文並引入錯誤。

aliases' => ['std' => stdClass::class, 'standard' => 'std'] 
廣告
© . All rights reserved.