根据环境自动装配 symfony CacheInterface

Autowire symfony CacheInterface depending on environment

我正在尝试在我的环境中使用不同的缓存系统。例如,我想 Filesystem 用于 devmemcached 用于 prod.

我正在使用 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: ~

但现在我无法为 test 环境提供另一个缓存系统,例如 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'

Symfony 3.3+/4 和 2017/2019 中,您可以省略任何配置依赖并使用 工厂模式 [=28= 完全控制行为]:

// 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 Documentation 中查看有关服务工厂的更多信息。


您可以在我的 Why Config Coding Sucks post.

中阅读更多相关信息

尽管工厂模式是解决此类问题的一个很好的选择,但通常您不需要为 Symfony 缓存系统这样做。输入提示 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 服务默认不可用,您可能需要手动定义它。