微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php-Laravel自动注入和在构造函数主体中手动指定依赖项之间有什么区别?

我在Laravel项目中使用存储库模式.官方文档except for this snippet中并没有真正解释这种模式:

You may type-hint a repository defined by your application in a controller’s constructor. The repository will automatically be resolved and injected into the class.

根据文档,这是我的代码

class CategoriesController extends Controller
{
    protected $repo;

    public function __construct(CategoriesRepository $repo)
    {
        $this->repo = $repo;
    }

我已经提示了CategoriesRepository,因此服务容器会自动加载它.

但是,如果直接创建CategoriesController类的新实例(不使用Service Container),则必须指定我也需要CategoriesRepository的新实例,如下所示:

$example = new CategoriesController(new CategoriesRepository());

现在,让我们假设我编写以下代码.

class CategoriesController extends Controller
{
    protected $repo;

    public function __construct()
    {
        $this->repo = new CategoriesRepository();
    }

这样,我不必通过服务容器加载类,也不必通过传递CategoriesRepository的新实例作为参数来调用它,因为它是在构造函数内部自动创建的.

所以,我的问题是:这是不好的做法吗?作为参数的类型提示与在构造函数内部创建新实例之间有什么区别?

解决方法:

这是依赖注入的优点:

复杂的初始化

class MyController {

     public function __construct(A $a) { }
}

class A {
     public function __construct(B $b) { }
}
class B {
     public function __construct(C $c) { }
}

class C {
     public function __construct(D $d) { }
}
class D {
     public function __construct() { }
}

现在您可以要求laravel为您创建该类,例如:

$controller = make(MyController::class);

或者您可以执行以下操作:

$controller = new MyController(new A(new B(new C(new D())))));

另外,您可以指定关于如何创建变量的更复杂的规则:

app()->bind(D::class, function ($app) {
       $d = new D();
       $d->setValueOfSomething($app->make(AnotherClass::class));
       return $d;
});

测试中

这是依赖注入比手动创建事物的优势之一.另一个是单元测试:

    public function testSomeFunctionOfC() {
        $this->app->bind(D::class, function () {
               $dMock = $this->createMock(D::class);
        });
        $c = make(C::class);
    }

现在,当您创建C时,类D将成为模拟类,您可以确保该类根据您的规范工作.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐