English 中文(简体)
Zend Framework - Service Manager
  • 时间:2024-11-05

Zend Framework - Service Manager


Previous Page Next Page  

The Zend Framework includes a powerful service locator pattern implementation called zend-servicemanager. Zend framework extensively uses the service manager for all its functionapties. The Service Manager provides a high-level abstraction for the Zend Framework. It also integrates nicely with all the other components of the Zend Framework.

Install Service Manager

The Service Manager component can be installed using the composer tool.

composer require zendframework/zend-servicemanager

Example

First, all the services need to be registered into the service manager. Once the services are registered into the server manager system, it can be accessed at any time with minimal efforts. The service manager provides a lot of options to register the service. A simple example is as follows −

use ZendServiceManagerServiceManager; 
use ZendServiceManagerFactoryInvokableFactory; 
use stdClass;  
$serviceManager = new ServiceManager([ 
    factories  => [stdClass::class => InvokableFactory::class,], 
]);

The above code registers the stdClass into the system using the Factory option. Now, we can get an instance of the stdClass at any time using the get() method of the service manager as shown below.

use ZendServiceManagerServiceManager;  
$object = $serviceManager->get(stdClass::class);

The get() method shares the retrieved object and so, the object returned by calpng the get() method multiple times is one and the same instance. To get a different instance every time, the service manager provides another method, which is the build() method.

use ZendServiceManagerServiceManager;  
$a = $serviceManager->build(stdClass::class); 
$b = $serviceManager->build(stdClass::class);

Service Manager Registration

The service manager provides a set of methods to register a component. Some of the most important methods are as given below −

    Factory method

    Abstract factory method

    Initiapzer method

    Delegator factory method

We will discuss each of these in detail in the upcoming chapters.

Factory Method

A factory is basically any callable or any class that implements the FactoryInterface (ZendServiceManagerFactoryFactoryInterface).

The FactoryInterface has a single method −

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

The arguments details of the FactoryInterface is as follows −

    container (ContainerInterface) − It is the base interface of the ServiceManager. It provides an option to get other services.

    requestedName − It is the service name.

    options − It gives additional options needed for the service.

Let us create a simple class implementing the FactoryInterface and see how to register the class.

Class Test - Object to be Retrieved

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

The Test class depends on the stdClass.

Class TestFactory - Class to Initiapze Test Object

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

The TestFactory uses a container to retrieve the stdClass, creates the instance of the Test class, and returns it.

Registration and Usage of the Zend Framework

Let us now understand how to register and use the Zend Framework.

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

The service manager provides a special factory called InvokableFactory to retrieve any class which has no dependency. For example, the stdClass can be configured using the InvokableFactory since the stdClass does not depend on any other class.

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

Another way to retrieve an object without implementing the FactoryInterface or using the InvokableFactory is using the inpne method as given below.

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

Abstract Factory Method

Sometimes, we may need to create objects, which we come to know only at runtime. This situation can be handled using the AbstractFactoryInterface, which is derived from the FactoryInterface.

The AbstractFactoryInterface defines a method to check whether the object can be created at the requested instance or not. If object creation is possible, it will create the object using the __invokemethod of the FactoryInterface and return it.

The signature of the AbstractFactoryInterface is as follows −

pubpc function canCreate(ContainerInterface $container, $requestedName) 

Initiapzer Method

The Initiapzer Method is a special option to inject additional dependency for already created services. It implements the InitiapzerInterface and the signature of the sole method available is as follows −

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

In the above example, the method checks whether the instance is of type EventManagerAwareInterface. If it is of type EventManagerAwareInterface, it sets the event manager object, otherwise not. Since, the method may or may not set the dependency, it is not repable and produces many runtime issues.

Delegator Factory Method

Zend Framework supports delegators pattern through DelegatorFactoryInterface. It can be used to decorate the service.

The signature of this function is as follows −

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

Here, the $callback is responsible for decorating the service instance.

Lazy Services

Lazy service is one of those services which will not be fully initiapzed at the time of creation. They are just referenced and only initiapzed when it is really needed. One of the best example is database connection, which may not be needed in all places. It is an expensive resource as well as have time-consuming process to create. Zend framework provides LazyServiceFactory derived from the DelegatorFactoryInterface, which can produce lazy service with the help of the Delegator concept and a 3rd party proxy manager, which is called as the ocramius proxy manager.

Plugin Manager

Plugin Manager extends the service manager and provides additional functionapty pke instance vapdation. Zend Framework extensively uses the plugin manager.

For example, all the vapdation services come under the VapdationPluginManager.

Configuration Option

The service manager provides some options to extend the feature of a service manager. They are shared, shared_by_default and apases. As we discussed earper, retrieved objects are shared among requested objects by default and we can use the build() method to get a distinct object. We can also use the shared option to specify which service to be shared. The shared_by_default is same as the shared feature, except that it apppes for all 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 apppes to all service 
]);

The apases option can be used to provide an alternative name to the registered services. This have both advantages and disadvantages. On the positive side, we can provide alternative short names for a service. But, at the same time, the name may become out of context and introduce bugs.

apases  => [ std  => stdClass::class,  standard  =>  std ] 
Advertisements