我的理解:
所以在这一点上,我开始尝试将 IoC 容器用于更复杂的场景。到目前为止,似乎为了使用 IoC 容器,对于我想创建的几乎所有具有它想要在 IoC 容器中定义的依赖项的类,我都只能使用 has-a 关系。如果我想创建一个继承类的类,但前提是父类是以特定方式创建的,它在 IoC 容器中注册了怎么办。
所以举个例子:我想创建一个mysqli的子类,但是我想在IoC容器中注册这个类,只用我之前在IoC容器中注册的方式构造的父类进行实例化。我想不出不复制代码的方法(因为这是一个学习项目,我试图让它尽可能“纯”)。 Here are some more examples of what I am trying to describe.
所以这里是我的一些问题:
最佳答案
简单地说(因为它不是仅限于 OOP 世界的问题),一个 依赖 在这种情况下,组件 A 需要(依赖)组件 B 来做它应该做的事情。该词还用于描述此场景中的依赖组件。用 OOP/PHP 术语来说,请考虑以下带有强制性汽车类比的示例:
class Car {
public function start() {
$engine = new Engine();
$engine->vroom();
}
}
Car
取决于 Engine
. Engine
是 Car
的依赖。不过这段代码很糟糕,因为:Car
的代码 Engine
与 MockEngine
用于测试目的或 TurboEngine
在不修改 Car
的情况下扩展原始的. 依赖注入(inject) 是通过使
Car
成为事实来解决所有这些问题的一种方式。需求Engine
明确并明确地为其提供一个:class Car {
protected $engine;
public function __construct(Engine $engine) {
$this->engine = $engine;
}
public function start() {
$this->engine->vroom();
}
}
$engine = new SuperDuperTurboEnginePlus(); // a subclass of Engine
$car = new Car($engine);
以上是的例子构造函数注入(inject) ,其中依赖(被依赖对象)通过类构造函数提供给被依赖者(消费者)。另一种方法是暴露
setEngine
Car
中的方法类并使用它来注入(inject) Engine
的实例.这被称为 二传手注入(inject)并且主要用于应该在运行时交换的依赖项。任何重要的项目都由一堆相互依赖的组件组成,并且很容易很快就会忘记什么被注入(inject)到哪里。一个 依赖注入(inject)容器 是一个对象,它知道如何实例化和配置其他对象,知道它们与项目中其他对象的关系并为您进行依赖注入(inject)。这使您可以集中管理所有项目的(相互)依赖项,更重要的是,可以更改/模拟其中的一个或多个,而无需编辑代码中的一堆位置。
让我们抛开汽车类比,以 OP 试图实现的目标为例。假设我们有一个
Database
对象取决于 mysqli
目的。假设我们想使用一个非常原始的依赖检测容器类 DIC
公开两个方法:register($name, $callback)
注册在给定名称下创建对象的方法和 resolve($name)
从该名称获取对象。我们的容器设置看起来像这样:$dic = new DIC();
$dic->register('mysqli', function() {
return new mysqli('somehost','username','password');
});
$dic->register('database', function() use($dic) {
return new Database($dic->resolve('mysqli'));
});
请注意,我们告诉容器获取
mysqli
的实例。从自身组装 Database
的实例.然后得到一个Database
自动注入(inject)其依赖项的实例,我们只需:$database = $dic->resolve('database');
这就是它的要点。一个更复杂但仍然相对简单且易于掌握的 PHP DI/IoC 容器是 Pimple .查看其文档以获取更多示例。
关于 OP 的代码和问题:
mysqliWrapper
类扩展 mysql
或依赖它。 IoC
从内部 mysqliWrapper
您正在将一种依赖项交换为另一种依赖项。你的对象不应该知道或使用容器;否则它不再是 DIC,而是服务定位器(反)模式。 require
一个类文件,然后再将其注册到容器中,因为您根本不知道是否要使用该类的对象。在一处完成所有容器设置。如果您不使用自动加载器,您可以 require
在您向容器注册的匿名函数中。 其他资源:
关于php - 了解 IoC 容器和依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18562752/