ZendFramework-サービスマネージャー

Zend Frameworkには、と呼ばれる強力なサービスロケーターパターンの実装が含まれています zend-servicemanager。Zend Frameworkは、そのすべての機能にサービスマネージャーを幅広く使用しています。Service Managerは、ZendFrameworkの高レベルの抽象化を提供します。また、ZendFrameworkの他のすべてのコンポーネントとうまく統合されます。

ServiceManagerをインストールします

Service Managerコンポーネントは、 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,], 
]);

上記のコードは、 stdClass を使用してシステムに Factoryオプション。これで、stdClassのインスタンスをいつでも使用して取得できます。get() 以下に示すサービスマネージャの方法。

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

get()メソッドは取得したオブジェクトを共有するため、get()メソッドを複数回呼び出して返されるオブジェクトは1つの同じインスタンスです。毎回異なるインスタンスを取得するために、サービスマネージャーは別のメソッドを提供します。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を実装する簡単なクラスを作成し、クラスを登録する方法を見てみましょう。

クラステスト-取得するオブジェクト

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

ザ・ Test クラスはstdClassに依存します。

クラスTestFactory-テストオブジェクトを初期化するクラス

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クラスのインスタンスを作成して、それを返します。

ZendFrameworkの登録と使用

ZendFrameworkを登録して使用する方法を理解しましょう。

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

サービスマネージャーは、と呼ばれる特別な工場を提供します InvokableFactory依存関係のないクラスを取得します。たとえば、stdClass stdClassは他のクラスに依存しないため、InvokableFactoryを使用して構成できます。

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は、要求されたインスタンスでオブジェクトを作成できるかどうかを確認するメソッドを定義します。オブジェクトの作成が可能な場合は、を使用してオブジェクトを作成します__invokemethod FactoryInterfaceのを返し、それを返します。

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 サービスインスタンスの装飾を担当します。

怠惰なサービス

レイジーサービスは、作成時に完全に初期化されないサービスの1つです。それらは参照されるだけで、本当に必要な場合にのみ初期化されます。最良の例の1つはデータベース接続ですが、これはすべての場所で必要なわけではありません。これは高価なリソースであるだけでなく、作成するのに時間のかかるプロセスがあります。ZendフレームワークはLazyServiceFactory から派生 DelegatorFactoryInterface、の助けを借りて怠惰なサービスを生み出すことができます Delegator コンセプトとサードパーティのプロキシマネージャー。 ocramius proxy manager

プラグインマネージャー

プラグインマネージャーはサービスマネージャーを拡張し、インスタンス検証などの追加機能を提供します。Zend Frameworkは、プラグインマネージャーを幅広く使用しています。

たとえば、すべての検証サービスは ValidationPluginManager

構成オプション

サービスマネージャは、サービスマネージャの機能を拡張するためのいくつかのオプションを提供します。彼らですshared, shared_by_default そして aliases。前に説明したように、取得されたオブジェクトはデフォルトで要求されたオブジェクト間で共有され、build()個別のオブジェクトを取得するメソッド。使用することもできますshared共有するサービスを指定するオプション。ザ・shared_by_default と同じです shared すべてのサービスに適用されることを除いて、機能。

$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']