1

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

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

基本上我想完成相当于这个:

块.php

class Block {

     private $filepath;

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

}

页面.php

class Page {

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

}

我正在为我的容器使用 Pimple,如下所示:

引导程序.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 反模式。所以以下是错误的代码:

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 工厂?

4

1 回答 1

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 容器根据需要传递对象。

于 2017-12-24T21:19:11.480 回答