Zend Framework - Administrador de servicios

Zend Framework incluye una potente implementación de patrones de localización de servicios llamada zend-servicemanager. Zend framework utiliza ampliamente el administrador de servicios para todas sus funcionalidades. El Administrador de servicios proporciona una abstracción de alto nivel para Zend Framework. También se integra muy bien con todos los demás componentes de Zend Framework.

Instalar Service Manager

El componente Service Manager se puede instalar utilizando el composer herramienta.

composer require zendframework/zend-servicemanager

Ejemplo

Primero, todos los servicios deben registrarse en el administrador de servicios. Una vez que los servicios están registrados en el sistema del administrador del servidor, se puede acceder a él en cualquier momento con un mínimo esfuerzo. El administrador de servicios ofrece muchas opciones para registrar el servicio. Un ejemplo simple es el siguiente:

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

El código anterior registra el stdClass en el sistema usando el Factoryopción. Ahora, podemos obtener una instancia de stdClass en cualquier momento usando elget() método del administrador de servicios como se muestra a continuación.

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

El método get () comparte el objeto recuperado y, por tanto, el objeto devuelto al llamar al método get () varias veces es una y la misma instancia. Para obtener una instancia diferente cada vez, el administrador de servicios proporciona otro método, que es elbuild() método.

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

Registro de administrador de servicios

El administrador de servicios proporciona un conjunto de métodos para registrar un componente. Algunos de los métodos más importantes son los que se indican a continuación:

  • Método de fábrica
  • Método de fábrica abstracto
  • Método de inicialización
  • Método de fábrica del delegador

Discutiremos cada uno de estos en detalle en los próximos capítulos.

Método de fábrica

Una fábrica es básicamente cualquier invocable o cualquier clase que implemente el FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface).

FactoryInterface tiene un solo método:

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

Los detalles de los argumentos de FactoryInterface son los siguientes:

  • container (ContainerInterface)- Es la interfaz base del ServiceManager. Brinda una opción para obtener otros servicios.

  • requestedName - Es el nombre del servicio.

  • options - Brinda opciones adicionales necesarias para el servicio.

Creemos una clase simple implementando FactoryInterface y veamos cómo registrar la clase.

Prueba de clase - Objeto a recuperar

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

los Test la clase depende de stdClass.

Class TestFactory - Clase para inicializar el objeto de prueba

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

TestFactory usa un contenedor para recuperar stdClass, crea la instancia de la clase Test y la devuelve.

Registro y uso de Zend Framework

Ahora entendamos cómo registrar y usar Zend Framework.

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

El gerente de servicio proporciona una fábrica especial llamada InvokableFactorypara recuperar cualquier clase que no tenga dependencia. Por ejemplo, elstdClass se puede configurar usando InvokableFactory ya que stdClass no depende de ninguna otra clase.

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

Otra forma de recuperar un objeto sin implementar la FactoryInterface o usando el InvokableFactory está utilizando el método en línea como se indica a continuación.

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

Método de fábrica abstracta

A veces, es posible que necesitemos crear objetos, que llegamos a conocer solo en tiempo de ejecución. Esta situación se puede manejar utilizando elAbstractFactoryInterface, que se deriva de FactoryInterface.

AbstractFactoryInterface define un método para verificar si el objeto se puede crear en la instancia solicitada o no. Si la creación de objetos es posible, creará el objeto usando el__invokemethod de FactoryInterface y devuélvalo.

La firma de AbstractFactoryInterface es la siguiente:

public function canCreate(ContainerInterface $container, $requestedName)

Método de inicialización

El método de inicialización es una opción especial para inyectar dependencia adicional para servicios ya creados. Implementa laInitializerInterface y la firma del único método disponible es la siguiente:

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

En el ejemplo anterior, el método comprueba si la instancia es de tipo EventManagerAwareInterface. Si es de tipoEventManagerAwareInterface, establece el objeto administrador de eventos, de lo contrario no. Dado que el método puede o no establecer la dependencia, no es confiable y produce muchos problemas de tiempo de ejecución.

Método de fábrica del delegador

Zend Framework admite el patrón de delegadores a través de DelegatorFactoryInterface. Se puede utilizar para decorar el servicio.

La firma de esta función es la siguiente:

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

Aquí el $callback es responsable de decorar la instancia de servicio.

Servicios perezosos

El servicio Lazy es uno de esos servicios que no se inicializará por completo en el momento de su creación. Solo se hace referencia a ellos y solo se inicializan cuando es realmente necesario. Uno de los mejores ejemplos es la conexión a la base de datos, que puede no ser necesaria en todos los lugares. Es un recurso costoso y requiere mucho tiempo para crearlo. Zend framework proporcionaLazyServiceFactory derivado de la DelegatorFactoryInterface, que puede producir un servicio perezoso con la ayuda del Delegator concepto y un administrador de proxy de terceros, que se denomina como el ocramius proxy manager.

Plugin Manager

Plugin Manager amplía el administrador de servicios y proporciona funciones adicionales como la validación de instancias. Zend Framework utiliza ampliamente el administrador de complementos.

Por ejemplo, todos los servicios de validación se encuentran bajo el ValidationPluginManager.

Opción de configuración

El administrador de servicios ofrece algunas opciones para ampliar la función de un administrador de servicios. Sonshared, shared_by_default y aliases. Como discutimos anteriormente, los objetos recuperados se comparten entre los objetos solicitados de forma predeterminada y podemos usar labuild()método para obtener un objeto distinto. También podemos utilizar elsharedopción para especificar qué servicio se compartirá. losshared_by_default es igual que el shared característica, excepto que se aplica a todos los servicios.

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

los aliasesLa opción se puede utilizar para proporcionar un nombre alternativo a los servicios registrados. Esto tiene ventajas y desventajas. En el lado positivo, podemos proporcionar nombres cortos alternativos para un servicio. Pero, al mismo tiempo, el nombre puede quedar fuera de contexto e introducir errores.

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