Laravel自动注入和在构造函数体中手动指定依赖项之间有什么区别?(What's the difference between Laravel automatic injection an

编程入门 行业动态 更新时间:2024-10-28 12:16:12
Laravel自动注入和在构造函数体中手动指定依赖项之间有什么区别?(What's the difference between Laravel automatic injection and manually specifying the dependencies in the constructor body?)

我在Laravel项目中使用了Repository模式。 除了此代码段之外,官方文档中没有真正解释此模式:

您可以在控制器的构造函数中键入提示由应用程序定义的存储库。 存储库将自动解析并注入到类中。

这是我的代码,根据文档:

class CategoriesController extends Controller { protected $repo; public function __construct(CategoriesRepository $repo) { $this->repo = $repo; }

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

但是,如果我直接创建CategoriesController类的新实例(不使用服务容器),我必须指定我还需要CategoriesRepository的新实例,如下所示:

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

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

class CategoriesController extends Controller { protected $repo; public function __construct() { $this->repo = new CategoriesRepository(); }

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

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

I'm using a Repository pattern in my Laravel project. This pattern is not really explained in the official documentation, 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.

This is my code, in accordance with the documentation:

class CategoriesController extends Controller { protected $repo; public function __construct(CategoriesRepository $repo) { $this->repo = $repo; }

I've type-hinted the CategoriesRepository so it gets automatically loaded by the Service Container.

However, if I directly create a new instance of the CategoriesController class (without using the Service Container), I have to specify that I need a new instance of the CategoriesRepository too, like this:

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

Now, let's suppose I write the following code.

class CategoriesController extends Controller { protected $repo; public function __construct() { $this->repo = new CategoriesRepository(); }

This way, I don't have to load the class through the Service Container, nor call it by passing a new instance of CategoriesRepository as the argument, because it's automatically created inside of the constructor.

So, my question is: would this be bad practice? What's the difference between type-hinting as a parameter and creating a new instance inside of the constructor?

最满意答案

这是依赖注入的美妙之处:

复杂初始化

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将是模拟类,您可以根据您的规范确保工作。

Here's the beauty of dependency injection:

Complex initialization

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() { } }

Now you can ask laravel to create that class for you e.g:

$controller = make(MyController::class);

or you can do:

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

In addition you can specify more complex rules on how to create the variables:

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

Testing

That's one advantage of dependency injection over manual creation of things. Another is unit testing:

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

Now when you create C the class D will be the mocked class instead which you can ensure works according to your specification.

更多推荐

本文发布于:2023-07-16 00:09:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1120986.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:有什么区别   函数   automatic   difference   Laravel

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!