-
Notifications
You must be signed in to change notification settings - Fork 1
Abstract Factory
It is recommended to use Laminas ServiceManager instead of PHP-DI as container provider
new Itseasy\Application([
...
'container_provider' => Itseasy\ServiceManager\LaminasServiceManager::class
...
]);
Abstract factory will only be call when explicit factory definition is not found
The result of abstract factory then will be cache and become explicit factory definition in memory
Large and many Abstract Factory might cause slower performance in code execution
Note that Abstract Factory doesn't support constructor hence no dependency can be injected for the factory
Container can only be access when invoke is call
Example Abstract Factory
Auto Creating GenericRepository without defining Repository in the service factories
Rename Project to your Namespace
<?php
declare(strict_types=1);
namespace Project\Repository\Factory;
use Laminas\ServiceManager\Factory\AbstractFactoryInterface;
use Psr\Container\ContainerInterface;
use Itseasy\Repository\GenericRepository;
use Project\Database;
class RepositoryAbstractServiceFactory implements AbstractFactoryInterface
{
public const SERVICE_SUFFIX = 'Repository';
public function __invoke(
ContainerInterface $container,
$requestedName,
?array $options = null
) {
$namespace = explode("\\", $requestedName);
$repository = preg_split('/(?=[A-Z])/', end($namespace), -1, PREG_SPLIT_NO_EMPTY);
array_pop($repository);
$table_name = strtolower(implode("_", $repository));
return new GenericRepository($container->get(Database::class), $table_name);
}
public function canCreate(ContainerInterface $container, $requestedName)
{
$namespace = explode("\\", $requestedName);
if (strpos(end($namespace), self::SERVICE_SUFFIX) > -1) {
return true;
}
return false;
}
}
Then register abstract factories in the service.config.php2
<?php
return [
"service" => [
"abstract_factories" => [
Project\Repository\Factory\RepositoryAbstractServiceFactory::class
]
]
];
Next time when we call a Repository in a Factory
...
// This will create repository class that mange database table "user_role"
$container->get("UserRoleRepository");
// This will create repository class that mange database table "project"
$container->get("ProjectRepository");
...