2

我正在为依赖注入容器的想法而苦苦挣扎。

不知道如何解释,但我会尝试几个例子:

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 如何确定他需要创建什么?

4

2 回答 2

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 中,通过自动加载,容器无法知道您项目的所有类。所以总而言之,它无法猜测要注入什么实现。

因此,像上面一样,您必须手动定义要使用的实现(配置文件,...)

于 2013-07-09T09:59:36.533 回答
0

我最好的选择是 PHP 中的 IoC 容器使用反射(就像 .NET 和 Java 中的 IoC 容器一样)。下面是一个示例,展示了如何反射一个类型并获取其构造函数的参数名称:

$reflector = new ReflectionClass('SomeClass'); 

$parameters = $reflector->getConstructor()->getParameters();

foreach ($parameters as $parameter) {
    echo $parameter->name;
}
于 2013-07-03T19:10:15.020 回答