我仍在尝试使用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工厂?
答案 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容器根据需要传递对象。