如何使用Pimple for Dependency Injection在另一个类中最好地使用对象工厂?

时间:2017-12-19 16:59:17

标签: php dependency-injection pimple

我仍在尝试使用Pimple来解决依赖注入设计模式的某些方面。我完全理解使用属于类Foo的构造函数或setter函数来建立它对类Bar的依赖。

我不太了解的部分是如何在使用Pimple工厂时从属于Foo的方法中正确实例化类Bar的多个新实例。

基本上我想完成相同的工作:

Block.php

class Block {

     private $filepath;

     public function setFilePath($filepath) {
          $this->filepath = $filepath;
     }

}

page.php文件

class Page {

     private function newBlock() {
          //do something here to get $filepath
          $block = new Block();
          $block->setFilePath($filepath);
          return $block;
     }

}

我正在使用Pimple作为我的容器:

bootstrap.php中

$container = new Container();

$container['page'] = $container->factory(function ($c) {
    return new Page();
});

$container['block'] = $container->factory(function ($c) {
     return new Block();
});

这个想法是可以定义多个页面,每个页面可能包含多个块。每个块的属性由Page中的方法定义。它需要使用完全解耦的代码来实现。

据我了解,将整个容器作为依赖项注入到Page实际上是Service Locator反模式。所以以下是BAD代码:

class Page {

     private $container;

     public function __construct(Container $container) {
          $this->container = $container;
     }

     private function newBlock() {
          //do something here to get $filepath
          $block = $this->container['block'];
          $block->setFilePath($filepath);
          return $block;
     }

}

如何让Page能够使用DIC中定义的Block工厂?

1 个答案:

答案 0 :(得分:0)

因此,在DI容器设置中,您可以传递容器引用。因此,如果您需要在页面类中大量使用Block类,则可以执行以下操作:

$container = new Container();

$container['page'] = $container->factory(function ($c) {
    return new Page( $c['block'] );
});

$container['block'] = $container->factory(function ($c) {
     return new Block();
});

但这意味着您必须向Page类的构造函数添加一个参数:

class Page {

    private $block = NULL;

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

     private function newBlock() {
          //do something here to get $filepath
          $this->block->setFilePath($filepath);
          return $this->block;
     }

}

因此,我们实际上并没有将整个容器传递到每个类中,而是允许DI容器根据需要传递对象。