I am trying to use different cache system on my environments. I would like to have, for example, Filesystem
for dev and memcached
for prod.
I am using symfony 3.3.10.
To achieve this, I would like to autowire the CacheInterface as follow:
use PsrSimpleCacheCacheInterface;
class Api {
public function __construct(CacheInterface $cache)
{
$this->cache = $cache;
}
}
Here are my configuration files:
config_dev.yml:
framework:
cache:
app: cache.adapter.filesystem
config_prod.yml:
framework:
cache:
app: cache.adapter.memcached
...
The error disappears when the FilesystemCache is declared as a service:
services:
SymfonyComponentCacheSimpleFilesystemCache: ~
But now I cannot have another cache system for the test environment like NullCache. In fact, I have to declare only one service inheriting from CacheInterface. It is not possible as config_test is using config_dev too.
This is the beginning of services.yml if it can help:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Any idea on how to autowire different cache system depending on the environment?
EDIT:
Here is the working configuration:
use PsrCacheCacheItemPoolInterface;
class MyApi
{
/**
* @var CacheItemPoolInterface
*/
private $cache;
public function __construct(CacheItemPoolInterface $cache)
{
$this->cache = $cache;
}
}
config.yml:
framework:
# ...
cache:
pools:
app.cache.api:
default_lifetime: 3600
services.yml:
# ...
PsrCacheCacheItemPoolInterface:
alias: 'app.cache.api'
2
Answers
In Symfony 3.3+/4 and 2017/2019 you can omit any config dependency and keep full control of the behavior with factory pattern:
And
services.yml
of course:See more about service factory in Symfony Documentation.
You can read more about this in my Why Config Coding Sucks post.
Even though factory pattern is a good option to solve this kind of problem, normally you don’t need to do that for Symfony cache system. Typehints
CacheItemPoolInterface
instead:It automatically injects the current
cache.app
service depending on the active environment, so Symfony does the job for you!Just make sure to configure the
framework.cache.app
for each environment config file:As
cache.adapter.null
service isn’t available by default, you might need to define it manually.