Autowire Symfony CacheInterface в зависимости от среды

Я пытаюсь использовать другую систему кэширования в моей среде. Я хотел бы, например, Filesystem за DEV а также memcached за тычок.

я использую Symfony 3.3.10.

Чтобы достичь этого, я бы хотел CacheInterface следующим образом:

use Psr\SimpleCache\CacheInterface;

class Api {

public function __construct(CacheInterface $cache)
{
$this->cache = $cache;
}
}

Вот мои файлы конфигурации:

config_dev.yml:

framework:
cache:
app: cache.adapter.filesystem

config_prod.yml:

framework:
cache:
app: cache.adapter.memcached
...

Вот ошибка, которую я получаю:
введите описание изображения здесь

Ошибка исчезает, когда FilesystemCache объявлен как услуга:

services:
Symfony\Component\Cache\Simple\FilesystemCache: ~

Но сейчас у меня не может быть другой кеш-системы для тестовое задание среда как NullCache. На самом деле, я должен объявить только один сервис, наследующий от CacheInterface. Это невозможно как config_test использует config_dev тоже.

Это начало services.yml если это может помочь:

services:
_defaults:
autowire: true
autoconfigure: true
public: false

Любая идея о том, как автоматически подключить кеш системы в зависимости от среды?

РЕДАКТИРОВАТЬ:

Вот рабочая конфигурация:

use Psr\Cache\CacheItemPoolInterface;

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:

# ...
Psr\Cache\CacheItemPoolInterface:
alias: 'app.cache.api'

2

Решение

Несмотря на то, что фабричный шаблон является хорошим вариантом для решения такого рода проблем, обычно вам не нужно делать это для кеш-системы Symfony. Typehints CacheItemPoolInterface вместо:

use Psr\Cache\CacheItemPoolInterface;

public function __construct(CacheItemPoolInterface $cache)

Это автоматически вводит текущий cache.app сервис в зависимости от активной среды, поэтому Symfony сделает всю работу за вас!

Просто убедитесь, что настроили framework.cache.app для каждого файла конфигурации среды:

# app/config/config_test.yml
imports:
- { resource: config_dev.yml }

framework:
#...
cache:
app: cache.adapter.null

services:
cache.adapter.null:
class: Symfony\Component\Cache\Adapter\NullAdapter
arguments: [~] # small trick to avoid arguments errors on compile-time.

Как cache.adapter.null сервис не доступен по умолчанию, вам может потребоваться определить его вручную.

5

Другие решения

Чтобы опустить любую конфигурационную зависимость и сохранить полный контроль над поведением, вы мог использовать фабричный образец:

// AppBundle/Cache/CacheFactory.php

namespace AppBundle\Cache;

final class CacheFactory
{
public function create(string $environment): CacheInterface
{
if ($environment === 'prod') {
// do this
return new ...;
}

// default
return new ...;
}
}

А также services.yml конечно:

# app/config/services.yml
services:
Psr\SimpleCache\CacheInterface:
factory: 'AppBundle\Cache\CacheFactory:create'
arguments: ['%kernel.environment%']

Подробнее о сервисной фабрике в Документация Symfony.


Дата примечания: Symfony 3.3+ и 2017

3