Software Engineering

ZF2: Factories

Services can be registered in the configuration as invokables and accessed anywhere in the application through the service locator. There’s a limitation though. The service is not able to use dependencies that are needed during the creation of the service. To solve this, Zend Framework 2 uses factories.

“In class-based programming, the factory method pattern is a creational pattern which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.”

— Wikipedia (http://en.wikipedia.org/wiki/Factory_method_pattern)

We start with a service:

namespace MyApplication\Model\Service;

class Service {

	public function __construct($config) {
		// something happens here that needs the Zend configuration
	}
}

It’s not possible here to use the service locator to access the configuration object, so we must use a factory. There are two ways to do this.

The first way is to register the service as a factory in the Zend Framework 2 configuration. To do this add it to the setServiceConfig function in the Module class:

public function getServiceConfig()
{
	return array(
		'factories' => array(
			'MyApplication\Service' => function (ServiceLocatorInterface $serviceLocator) {
				$config = $serviceLocator->get('Configuration');
				return new Service($config);
			},
		),
	);
}

To access the service just call the service locator:

$service = $sm->get('Service');

There’s a problem though. Creating the service using the configuration uses a closure, which means the configuration can’t be cached. To solve this problem we must create a factory class to handle the creation of the service class:

namespace MyApplication\Model\Service;

class ServiceFactory implements FactoryInterface {

	public function createService(ServiceLocatorInterface $serviceLocator) {
		$service = new Service();
		return $service;
	}
}

Add the ServiceFactory to the configuration file:

'service_manager' => array(
	'factories' => array(
		'Service'	=>	'MyApplication\Model\Service\ServiceFactory',
	),
),

The createService() function is part of Zend Framework 2’s implementation of the factory design pattern. It’s called internally by the framework. It’s not aware of the exact class that will be created (in our case the Service class).

The service class can now be accessed with the service locator in exactly the same way as above.

Previous Post Next Post

You Might Also Like

No Comments

Leave a Reply