使用类型提示和依赖关系注入


Using type hinting and dependency injection

我正在将对象传递到其构造函数中的类上使用类型提示。传递的对象 (Bar) 存在于其自己的命名空间中。这一切都很好,直到我用假对象交换传递的对象(用于单元测试目的)。我的测试 Bar 对象驻留在它自己的命名空间中,现在(非常正确地)抛出了一个错误。

use Some'Place'Bar
class Foo {
    // Passing a test Bar into here now throws error.
    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }
}

我是PHP的新手,所以不确定什么是可能的。有没有办法解决这个问题,或者我只需要从类中删除类型提示(这是我当前的解决方案)?

几个选项中的两个:

在实现接口 IBar 的构造函数中传递一个对象:

 interface IBar{
  function baz();
 }
 class Bar implements IBar{
    function baz(){ return $this->getSomethingExpensiveFromDatabase();}
 }
 class FakeBar implements IBar{
    function baz(){ return "baz";}
 }
 class Foo {
 function __construct(IBar $bar) ...

或者不使用类型提示

function __construct($bar) 

关键是,方法的签名永远不应该依赖于一个实现,而应该是一个接口。

编辑 :所以你只需要导入接口,然后导入假类,无论它来自哪里。然后,FakeBar可以模拟Bar。

类型杂耍是完全不同的事情,您在这里显示的是类型提示。不能传入具有相同类名但驻留在不同命名空间中的对象,但可以从从方法期望的类继承的类传入对象:

namespace Testing;
use Some'Place'Bar;
class TestingBar extends Bar {
}

然后,您可以将 TestingBar 的实例传递给您的方法。

如果你想对原始 Bar 类

和测试 Bar 类使用相同的名称,你需要将它们中的一个别名化掉(不过我建议不要这样做):

namespace Testing;
use Some'Place'Bar as OriginalBar;
class Bar extends OriginalBar {
}