An abstract factory is used when you cannot know the service names in advance (e.g., they are generated at runtime) but they follow a common creation pattern.
An abstract factory must implement Laminas\ServiceManager\Factory\AbstractFactoryInterface and provides two methods:
canCreate(ContainerInterface $container, $requestedName): Returns true if the factory is capable of creating the requested service.__invoke(ContainerInterface $container, $requestedName, array $options = null): Creates and returns the service.
Resolution Process
When get($name) is called:
- The Service Manager checks for an explicit factory mapping.
- If none is found, it iterates through registered
abstract_factories in order. - It calls
canCreate() on each. If true, it calls __invoke().
Best Practices
Limit the number of abstract factories. Because the Service Manager must iterate through them sequentially during lookups, having many abstract factories can be costly for performance. Mapping the same factory to multiple explicit services is usually a more efficient alternative.
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\AbstractFactoryInterface;
class MyAbstractFactory implements AbstractFactoryInterface
{
public function canCreate(ContainerInterface $container, $requestedName)
{
// Logic to determine if this factory can handle the request
return in_array('Traversable', class_implements($requestedName), true);
}
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new $requestedName();
}
}
$serviceManager = new ServiceManager([
'abstract_factories' => [
MyAbstractFactory::class
]
]);