如何在服务容器中实现单例访问?

时间:2015-11-14 01:39:17

标签: php dependency-injection singleton

我有一个类作为服务容器来管理提供者 一种依赖注入的方式。

class Container {

private $providers = array(); // providers array

public function __construct() {

}

/**
 * Sets the provider
 * @param string $name - provider's name
 * @param string|object|array|resource|closure - provider
 * @param boolean $singleton
 */
public function set($name, $provider, $singleton = false) {

    if ($singleton === false || ($singleton === true && !isset($this->providers[$name]))) {
        $this->providers[$name] = $provider;
    }
}

/**
 * Gets the provider
 * @param string $name
 * @param array $params
 * @return string|object|array|resource
 */
public function get($name, $params = array()) {

    if (isset($this->providers[$name])) {

        if (is_scalar($this->providers[$name]) || (is_object($this->providers[$name]) && !$this->providers[$name] instanceof Closure) || is_resource($this->providers[$name]) || is_array($this->providers[$name]))
            return $this->providers[$name];

        elseif ($this->providers[$name] instanceof Closure)
            // call a callback with an array of parameters
            return call_user_func_array($this->providers[$name], $params);

        else
            return "Provider type isn't correct.";
    }
    return "Provider " .$name. " doesn't exist.";
} }

现在,如果set方法中的第三个参数为true,我需要实现单例访问。因此,如果singleton == true,set方法应始终返回相同的结果实例。如果提供程序不是闭包,则将其视为常量。

例如:

$container = new Container();    

$dsn = "mysql:host=localhost;dbname=some_name"; // Host and db name
$user = "root"; // MySQL user name
$pass = "root"; // MySQL password

$container->set("db", function($dsn, $user, $pass) {
    return new \PDO($dsn, $user, $pass);
}, true);

$db_data = array($dsn, $user, $pass);

$db = $container->get("db", $db_data);
$db2 = $container->get("db", $db_data);
$db === $db2; // This should to return TRUE <--- This is the goal

如何解决这个问题?我没有使用任何框架,它应该是一个简单的通用解决方案,因为这只是一个例子,但是否则它不必是PDO类的实例。提供者可以是标量,对象,数组,资源或闭包。

0 个答案:

没有答案