优雅地使 Symfony 服务工厂失败的正确方法是什么?

What is the correct way to gracefully fail Symfony service factory?

Symfony's documentation for service factories 解释了如何允许服务容器使用工​​厂实例化服务,但没有解释创建失败时推荐的最佳实践是什么,即当服务出于任何原因不可用时。

例如;想象一个 Redis 内存缓存服务。在工厂 class 中,您有一个方法可以实例化 return Redis 客户端对象;

public function createRedisClient() {
  $redis = new \Redis();
  $connectionResult = $redis->connect($host, $port);

  return $redis;
}

如果 Redis 服务器暂时不可用,并且我希望能够优雅地回退到另一个解决方案来存储我们拥有的任何数据,工厂应该 return null,抛出是某种特定类型的例外,还是根本不关心可用性?

你可以使用PHP的is_object方法:

    public function createRedisClient() {
      $redis = new \Redis();
      $connectionResult = $redis->connect($host, $port);
      if (!is_object($redis)) {
        return false;
      }
      return $redis;
}

Return 值:

Returns TRUE 如果 var 是一个 object,否则为 FALSE。

参考:PHP is_object

如果你想要一个 "fallback" 解决方案,这里的最佳做法是将这些类型的服务分组在一个公共接口下,而不是像 "chain of responsibility" 那样尝试一次实例化一个服务:首先可以是实例化,returns。 当然,在您的客户端中,您将使用该界面,因此此过程对于 "client developer".

来说将是完全直接的

获得这个的最佳方法是拥有类似 SessionStorageFactory 的东西(所以是通用的),您可以在其中 "register" 所有具体工厂(RedisFactory,...,DefaultSessionStorageFactory) 并尝试一次实例化一个。

当然缺点是如果你可能需要一个 "superset" 的属性(比如 hostport 等等)除了具体的工厂之外对所有工厂都没有用其中需要参数。