我正在努力解决依赖注入容器的问题。
不确定如何解释,但我会尝试一些例子:
class foo
{
public function __construct(\Somenamespace\Bar $bar, $x)
{
}
}
DIC如何知道'x'会是什么?
如果我们走得更远,看看酒吧课。 DIC可以毫无问题地使用反射创建Bar。
namespace \Somenamespace;
class bar
{
public function __construct(\SomethingElse\Tap $tap, $y)
{
}
}
酒吧需要水龙头,DIC也可以找到水龙头但是它怎么知道'y'?
如果我们创建水龙头。
namespace\SomethingElse;
class tap
{
public function __construct($amountOfTaps)
{
}
}
DIC如何知道水龙头的数量或任何变量?
修改
如果提示类型是接口或抽象类,则同样的问题。 DIC如何弄清楚他需要创造什么?
答案 0 :(得分:2)
这是一个好的和有效的问题。
以下是其中一个可能的答案:容器无法知道
public function __construct(\Somenamespace\Bar $bar, $x)
$bar
是\Somenamespace\Bar
的一个实例,很简单$x
可能是任何东西......容器无法确切知道你想要什么。所以大多数容器都停在此处,并要求您明确定义(例如在配置文件中)应为$x
注入的依赖项。
然而某些容器可以尝试猜测。例如:
public function __construct($exportService)
容器可以假设变量名称可以是服务名称,因此它将尝试注入名为exportService
的依赖项。
我不知道任何PHP容器这样做,我打算将来在PHP-DI中实现它。
“界面注入”:
也是如此public function __construct(Some\GoodInterface $x)
在Java中,Container可以知道项目中的所有类(它们都归入WAR / JAR归档中)。因此Java容器可以查找接口的所有实现。
如果只有一个,它会自动使用它。
在PHP中,通过自动加载,容器无法知道项目的所有类。总而言之,它无法猜测要注入的实现。
如上所述,您必须手动定义要使用的实现(配置文件,...)
答案 1 :(得分:0)
我最好的选择是PHP中的IoC容器使用Reflection(就像.NET和Java中的IoC容器一样)。下面是一个示例,显示如何反映类型并获取其构造函数的参数的参数名称:
$reflector = new ReflectionClass('SomeClass');
$parameters = $reflector->getConstructor()->getParameters();
foreach ($parameters as $parameter) {
echo $parameter->name;
}