-
-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make it possible to decorate cache adapters with PSR6/PSR16 decorators through configuration #1
Comments
I've created something similar for a final class LoggerFactory
{
public const LOGGER_CONFIGURATIONS = 'loggers';
/**
* @psalm-var class-string<LoggerInterface>
*/
private $configurationIdentifier;
/**
* @psalm-param class-string<LoggerInterface> $configurationIdentifier References the configuration identifier
* within the {@see LoggerFactory::LOGGER_CONFIGURATIONS}
* configuration map.
*/
public function __construct(string $configurationIdentifier)
{
$this->configurationIdentifier = $configurationIdentifier;
}
public function __invoke(ContainerInterface $container): LoggerInterface
{
$config = $this->detectConfiguration($container, $this->configurationIdentifier);
return $container->get(LoggerFactoryInterface::class)->createLogger(
$this->configurationIdentifier,
$container,
$config
);
}
/**
* @return non-empty-array<string,mixed>
*/
private function detectConfiguration(ContainerInterface $container, string $configurationIdentifier): array
{
$config = $container->get('config');
Assert::isArrayAccessible($config);
$loggerConfigurations = $config[self::LOGGER_CONFIGURATIONS] ?? [];
Assert::isMap($loggerConfigurations);
$loggerConfigurationForIdentifier = $loggerConfigurations[$configurationIdentifier] ?? null;
if ($loggerConfigurationForIdentifier === null) {
throw new RuntimeException(sprintf(
'Cannot locate configuration for logger identifier %s',
$configurationIdentifier
));
}
Assert::isNonEmptyMap($loggerConfigurationForIdentifier);
return $loggerConfigurationForIdentifier;
}
} The project configurations looks like this:
ApplicationLoggerInterface interface ApplicationLoggerInterface extends \Psr\Log\LoggerInterface
{} Something like this could be achieved with both PSR-6 and PSR-16 interfaces. final class LoggerFactory implements LoggerFactoryInterface
{
private const WRAPPED_LOGGER_TEMPLATE = <<<'EOC'
return new class(%s) implements %s {
use \Psr\Log\LoggerTrait;
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
public function __construct(\Psr\Log\LoggerInterface $logger)
{
$this->logger = $logger;
}
public function log($level, $message, array $context = [])
{
$this->logger->log($level, $message, $context);
}
};
EOC;
public function createLogger(string $name, ContainerInterface $container, array $config): LoggerInterface
{
$this->assertInterfaceDoesNotImplementAnyOtherMethodThanPsrLoggerInterface($name);
/** @psalm-suppress MixedAssignment */
$wrappedLogger = eval(sprintf(self::WRAPPED_LOGGER_TEMPLATE, '$logger', $name));
assert($wrappedLogger instanceof LoggerInterface);
return $wrappedLogger;
}
/**
* @psalm-param class-string $name
* @psalm-assert class-string<LoggerInterface> $name
*/
private function assertInterfaceDoesNotImplementAnyOtherMethodThanPsrLoggerInterface(string $name): void
{
$reflection = new ReflectionClass($name);
if (!$reflection->isInterface()) {
throw InvalidLoggerConfigurationException::fromInvalidLoggerIdentifier($name);
}
if (!$reflection->implementsInterface(LoggerInterface::class)) {
throw InvalidLoggerConfigurationException::fromInvalidLoggerIdentifier($name);
}
$methodNames = $this->extractPublicMethodsFromReflection($reflection);
if ($methodNames !== $this->getLoggerInterfaceMethods()) {
throw InvalidLoggerConfigurationException::fromInvalidLoggerIdentifier($name);
}
}
private function extractPublicMethodsFromReflection(ReflectionClass $class): array
{
// omitted for readability
return [];
}
private function getLoggerInterfaceMethods(): array
{
// omitted for readability
return [];
}
} The main issue here is, that one has to verify that the interface which extends the Let me know what you think, I'm open for feedback. |
The midterm goal is to actually implement PSR interfaces directly via |
@weierophinney
Good morning,
The configuration provider currently provides the \Zend\Cache\Service\StorageCacheAbstractServiceFactory::class abstract factory which make it possible to map pseudo services. For instance:
However, currently, it seem that there is no way to decorate the adapters automatically with a PSR6 or PSR16 implementation. Could it be possible to add a decorator option to the adapters factory and if so, automatically return the decorated adapter? For instance:
For now, I make use of a delegator but...
Originally posted by @nuxwin at zendframework/zend-cache#179
The text was updated successfully, but these errors were encountered: