如何全局访问依赖注入容器

时间:2014-04-01 18:10:35

标签: php

我正在用PHP构建我自己的小型MVC框架,只是为了学习并更好地理解。

我用Router创建了一个小框架。

在我的index.php中,我为我的应用程序创建了一个容器。

的index.php

use \Oak\Route\Route as Route;
use \Oak\Route\Routes as Routes;
use \Oak\App\App as App;

$routes = new Routes();

$routes->addRoute(new Route('home', 'index', 'index'));
$routes->addRoute(new Route('user/{username}/{id}', 'index', 'about'));
$routes->addRoute(new Route('help', 'help', 'index'));

$container = new Container();
$container->set('app', function() use ($routes) {
    return new App($routes, new \Oak\Header\Request());
});

$app = $container->get('app');
$app->run();

Container.php& ContainerInterface.php

interface ContainerInterface {

public function set($name, $service);
public function get($name, array $params = array());
public function has($name);
public function remove($name);
public function clear();
}

class Container implements ContainerInterface {

    protected $services = array();

    public function set($name, $service) {
        if(!is_object($service)) {
            throw new InvalidArgumentException("Only objects can be registred");
        }

        if(!in_array($service, $this->services, true)) {
            $this->services[$name] = $service;
        }
        return $this;
    }

    public function get($name, array $params = array()) {
        if(!isset($this->services[$name])) {
            throw new RuntimeException($name ." has not been registred in the container");
        }
        $service = $this->services[$name];

        return !$service instanceof Closure ? $service : call_user_func_array($service, $params);
    }

    public function has($name):bool {
        return isset($this->services[$name]);
    }

    public function remove($name) {
        if(isset($this->services[$name])) {
            unset($this->services[$name]);
        }
        return $this;
    }

    public function clear() {
        $this->services = array();
    }

    public  function getServices():array {
        return $this->services;
    }
}

现在我的问题是如何从我的控制器,我的应用程序文件等启用对容器的访问。一种解决方案是在容器中使用Singleton还是静态方法?

我已经阅读了很多关于这个主题的博文和文章,但我似乎所有的例子只与索引文件中的容器进行通信?

我也开始尝试继承,该app扩展容器,然后将其传递给控制器​​?

我的问题是,您如何在应用中的任何位置启用对容器的访问权限,如果这样就可以了?

1 个答案:

答案 0 :(得分:0)

查看Singleton设计模式..你需要这样的东西:

class Container {
    private static $instance;
    //prevent from creating a container class by itself
    private function __construct() {};    
    /* .... */
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new Container();
        }
    }
}

然后代码中的所有地方而不是使用$container = new Container();使用$container = Container::getInstance();

无论如何,我强烈建议你检查一个疙瘩(http://pimple.sensiolabs.org/)这是非常好的代码,延迟加载。你需要花费大量的时间来写一些像疙瘩一样优秀且功能丰富的东西。