Zend Framework - Gestionnaire de services

Le Zend Framework comprend une puissante implémentation de modèle de localisateur de services appelée zend-servicemanager. Le framework Zend utilise largement le gestionnaire de services pour toutes ses fonctionnalités. Le gestionnaire de service fournit une abstraction de haut niveau pour le Zend Framework. Il s'intègre également parfaitement avec tous les autres composants du Zend Framework.

Installer Service Manager

Le composant Service Manager peut être installé à l'aide du composer outil.

composer require zendframework/zend-servicemanager

Exemple

Tout d'abord, tous les services doivent être enregistrés dans le gestionnaire de services. Une fois que les services sont enregistrés dans le système de gestion de serveur, il est accessible à tout moment avec un minimum d'efforts. Le gestionnaire de services propose de nombreuses options pour enregistrer le service. Un exemple simple est le suivant -

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

Le code ci-dessus enregistre le stdClass dans le système à l'aide du Factoryoption. Maintenant, nous pouvons obtenir une instance de stdClass à tout moment en utilisant leget() méthode du gestionnaire de services comme indiqué ci-dessous.

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

La méthode get () partage l'objet récupéré et ainsi, l'objet renvoyé en appelant la méthode get () plusieurs fois est une seule et même instance. Pour obtenir une instance différente à chaque fois, le gestionnaire de services fournit une autre méthode, qui est lebuild() méthode.

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

Inscription du gestionnaire de service

Le gestionnaire de services fournit un ensemble de méthodes pour enregistrer un composant. Certaines des méthodes les plus importantes sont indiquées ci-dessous -

  • Méthode d'usine
  • Méthode d'usine abstraite
  • Méthode d'initialisation
  • Méthode d'usine de délégué

Nous discuterons chacun de ces éléments en détail dans les prochains chapitres.

Méthode d'usine

Une fabrique est fondamentalement toute classe appelable ou toute classe qui implémente le FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).

FactoryInterface a une seule méthode -

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

Les détails des arguments de FactoryInterface sont les suivants -

  • container (ContainerInterface)- C'est l'interface de base du ServiceManager. Il offre une option pour obtenir d'autres services.

  • requestedName - C'est le nom du service.

  • options - Il donne des options supplémentaires nécessaires pour le service.

Créons une classe simple implémentant FactoryInterface et voyons comment enregistrer la classe.

Test de classe - Objet à récupérer

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

le Test la classe dépend de la classe stdClass.

Class TestFactory - Classe pour initialiser l'objet de test

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

TestFactory utilise un conteneur pour récupérer la classe stdClass, crée l'instance de la classe Test et la renvoie.

Enregistrement et utilisation du Framework Zend

Voyons maintenant comment enregistrer et utiliser le Framework Zend.

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

Le responsable du service fournit une usine spéciale appelée InvokableFactorypour récupérer toute classe qui n'a pas de dépendance. Par exemple, lestdClass peut être configuré à l'aide d'InvokableFactory puisque stdClass ne dépend d'aucune autre classe.

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

Une autre façon de récupérer un objet sans implémenter le FactoryInterface ou en utilisant le InvokableFactory utilise la méthode en ligne indiquée ci-dessous.

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

Méthode d'usine abstraite

Parfois, nous pouvons avoir besoin de créer des objets, que nous ne connaissons qu'au moment de l'exécution. Cette situation peut être gérée en utilisant leAbstractFactoryInterface, qui est dérivé de FactoryInterface.

AbstractFactoryInterface définit une méthode pour vérifier si l'objet peut être créé à l'instance demandée ou non. Si la création d'objet est possible, elle créera l'objet en utilisant le__invokemethod de FactoryInterface et renvoyez-le.

La signature de AbstractFactoryInterface est la suivante -

public function canCreate(ContainerInterface $container, $requestedName)

Méthode d'initialisation

La méthode d'initialisation est une option spéciale pour injecter une dépendance supplémentaire pour les services déjà créés. Il met en œuvre leInitializerInterface et la signature de la seule méthode disponible est la suivante -

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

Dans l'exemple ci-dessus, la méthode vérifie si l'instance est de type EventManagerAwareInterface. Si c'est de typeEventManagerAwareInterface, il définit l'objet du gestionnaire d'événements, sinon non. Étant donné que la méthode peut définir ou non la dépendance, elle n'est pas fiable et génère de nombreux problèmes d'exécution.

Méthode Delegator Factory

Zend Framework prend en charge le modèle de délégation via DelegatorFactoryInterface. Il peut être utilisé pour décorer le service.

La signature de cette fonction est la suivante -

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

Ici le $callback est responsable de la décoration de l'instance de service.

Services paresseux

Le service paresseux fait partie de ces services qui ne seront pas complètement initialisés au moment de la création. Ils sont simplement référencés et initialisés uniquement lorsque cela est vraiment nécessaire. L'un des meilleurs exemples est la connexion à la base de données, qui peut ne pas être nécessaire à tous les endroits. Il s'agit d'une ressource coûteuse et d'un processus de création long. Le framework Zend fournitLazyServiceFactory dérivé du DelegatorFactoryInterface, qui peut produire un service paresseux à l'aide du Delegator concept et un gestionnaire de proxy tiers, appelé ocramius proxy manager.

Gestionnaire de plugins

Plugin Manager étend le gestionnaire de services et fournit des fonctionnalités supplémentaires telles que la validation d'instance. Zend Framework utilise largement le gestionnaire de plugins.

Par exemple, tous les services de validation relèvent du ValidationPluginManager.

Option de configuration

Le gestionnaire de services propose certaines options pour étendre la fonctionnalité d'un gestionnaire de services. Elles sontshared, shared_by_default et aliases. Comme nous l'avons vu précédemment, les objets récupérés sont partagés entre les objets demandés par défaut et nous pouvons utiliser lebuild()méthode pour obtenir un objet distinct. Nous pouvons également utiliser lesharedoption pour spécifier le service à partager. leshared_by_default est le même que le shared fonction, sauf qu'elle s'applique à tous les services.

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

le aliasesL'option peut être utilisée pour fournir un nom alternatif aux services enregistrés. Cela présente à la fois des avantages et des inconvénients. Du côté positif, nous pouvons fournir des noms courts alternatifs pour un service. Mais, en même temps, le nom peut devenir hors contexte et introduire des bogues.

aliases' => ['std' => stdClass::class, 'standard' => 'std']