$wrappedBuzzer=newBuzzer();$eventManager=newZend\EventManager\EventManager();$eventManager->attach('buzz',function(){echo"Stare at the art!\n";});$buzzer=newBuzzerDelegator($wrappedBuzzer,$eventManager);echo$buzzer->buzz();// "Stare at the art!\nBuzz!"

This logic is fairly simple as long as you have access to the instantiation logic of the
$wrappedBuzzer object.

You may not always be able to define how $wrappedBuzzer is created, since a factory for it may be
defined by some code to which you don’t have access, or which you cannot modify without introducing further
complexity.

Delegator factories solve this specific problem by allowing you to wrap, decorate or modify any existing service.

A simple delegator factory for the buzzer service can be implemented as following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

useZend\ServiceManager\DelegatorFactoryInterface;useZend\ServiceManager\ServiceLocatorInterface;classBuzzerDelegatorFactoryimplementsDelegatorFactoryInterface{publicfunctioncreateDelegatorWithName(ServiceLocatorInterface$serviceLocator,$name,$requestedName,$callback){$realBuzzer=call_user_func($callback);$eventManager=$serviceLocator->get('EventManager');$eventManager->attach('buzz',function(){echo"Stare at the art!\n";});returnnewBuzzerDelegator($realBuzzer,$eventManager);}}

You can then instruct the service manager to handle the service buzzer as a delegate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

$serviceManager=newZend\ServiceManager\ServiceManager();$serviceManager->setInvokableClass('buzzer','Buzzer');// usually not under our control// as opposed to normal factory classes, a delegator factory is a// service like any other, and must be registered:$serviceManager->setInvokableClass('buzzer-delegator-factory','BuzzerDelegatorFactory');// telling the service manager to use a delegator factory to handle service 'buzzer'$serviceManager->addDelegator('buzzer','buzzer-delegator-factory');// now, when fetching 'buzzer', we get a BuzzerDelegator instead$buzzer=$serviceManager->get('buzzer');$buzzer->buzz();// "Stare at the art!\nBuzz!"

You can also call $serviceManager->addDelegator() multiple times, with the same or different delegator
factory service names. Each call will add one decorator around the instantiation logic of that particular
service.

Another way of configuring the service manager to use delegator factories is via configuration:

1
2
3
4
5
6
7
8
9
10
11
12

$config=array('invokables'=>array('buzzer'=>'Buzzer','buzzer-delegator-factory'=>'BuzzerDelegatorFactory',),'delegators'=>array('buzzer'=>array('buzzer-delegator-factory'// eventually add more delegators here),),);