依赖注入如何知道要传递哪些变量?

时间:2013-07-03 16:52:55

标签: php dependency-injection dependencies containers

我正在努力解决依赖注入容器的问题。

不确定如何解释,但我会尝试一些例子:

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如何弄清楚他需要创造什么?

2 个答案:

答案 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;
}