我正在尝试一些不同的设计模式来学习它们,并开始使用DI容器。
主代码(index.php)
$container = new 'League'Container'Container();
$container->add("config", function(){
return new Config(APP_ROOT . "/config.json");
});
$container->add("GoogleBooks", GoogleBooksProvider::class)
->withArgument( $container['config'] );
$container->add("books", BookRepository::class);
// empty array, as expected
var_dump($container['books']->getProviders());
// this line doesn't add the provider
$container['books']->addProvider( $container['GoogleBooks'] );
// empty array, should expect to have one entry, GoogleBooksProvider
var_dump($container['books']->getProviders());
BookRepository: addProvider
public function addProvider( iProvider $provider ) {
$this->_providers->push($provider);
return $this;
}
不像预期的那样工作,代码注释中描述的问题。但是,如果我交换
$container['books']->addProvider( $container['GoogleBooks'] );
$container['books'] = $container['books']->addProvider( $container['GoogleBooks'] );
通过将GoogleBooksProvider存储在BookRepository中,它可以正确工作。为什么我需要一个赋值运算符使其正确工作?
如果不将其放入容器中,则不需要赋值操作符,它将按预期工作。
$br = new BookRepository();
$br->addProvider( new GoogleBooksProvider($container['config']) );
// shows GoogleBooks is in the _providers array
var_dump($br->getProviders());
由于您是添加,而不是共享服务,因此每次访问容器时都要获取一个新的 BookRepository
实例:
var_dump($container['books'] === $container['books']); // false
如果你想共享BookRepository
,你需要使用这个:
$container->add("books", BookRepository::class, true);
或(短)
$container->singleton("books", BookRepository::class);