Laravel、依赖注入和 Eloquent

Laravel, Dependency Injection, and Eloquent

将 laravel 的依赖注入系统与 CRUD 模型等多实例对象一起使用的 right/best 方法是什么?

PHP某些角落的流行时尚-土地说下面的代码是"bad"

function someMethod()
{
    /* .. stuff ... */
    $object = new \App\SomeModel;
    $object->some_prop = 'some value';
    $object->save();
    /* .. other stuff ... */
}

这很糟糕,因为此方法现在依赖于新的对象实例化。当前的时尚认为应该通过某种依赖注入系统注入对象,例如 Laravel 的 automatic constructor dependency injection.

但是——注入 eloquent 模型似乎有问题

/*...*
public function __construct(\App\SomeModel $object)
{
    $this->someModel = $object;
}

function someMethod()
{
    /* .. stuff ... */
    $object = $this->someModel;
    $object->some_prop = 'some value';
    $object->save();
    /* .. other stuff ... */
}  
/*...*/           

尚不清楚Laravel的自动构造函数依赖注入是否每次都创建新实例,或者注入的对象是否为单实例对象。它也不处理您想使用 Eloquent 的静态助手

的情况
function someMethod($object_id)
{
    //another dependency
    \App\SomeModel::find($object_id);

    //but this doesn't work
    $this->someModel->find($object_id);
}    

在 Laravel 应用程序中是否有普遍接受的处理方法?有人说你应该注入工厂。其他人说存储库。我想知道 Laravel 开发人员 的一般做法是什么,如果 Laravel 附带任何可以帮助解决这里问题的东西(基础 factory/repository实现等)

我对此进行了一些尝试(没有认真测试),看起来这是可能的 - 事实上,我更喜欢这样做,并在未来期待它。下面的示例(未经测试):

use App/Models/Foo;

class FooController {

    private $model;

    public function __construct(Foo $model) 
    {
       $this->model = $model;
    }

    public function show(Request $request, $id)
    {
        $foo = $this->model->where($this->model->getKeyName(), '=', $id)->first();

        dd($foo);
    }

    public function store(Request $request)
    {
        $foo = $this->model->newInstance();
        $foo->bar = $request->get('baz');
        $foo->save();
    }

}

eloquent 外观上的查找帮助程序(例如 find)很不错,但本质上它们是标准的 where(...)->get()->first( ).

感谢 LaraChat Slack 的帮助,我自己解决了这个问题。

事实证明,除了自动构造函数依赖注入之外,Laravel 还有一种特殊形式的依赖注入,可以与 any of a router's callback methods/functions 一起使用.

考虑此代码示例

Route::get('api/users/{user?}', function (App\User $user) {
    return $user->email;
});

如果您使用变量 ({user}) 设置您的路由字符串,Laravel 将扫描您的路由处理程序的参数(上面是一个匿名函数,但它也适用于控制器方法)参数一个类型提示,其短 class 名称与变量名称匹配(上面的 App\User)。如果找到,Laravel 将实例化一个 loaded Eloquent 对象,而不是从 URL 传递参数。如果省略可选参数,您将获得指定类型的空白对象。

对 Laravel DI 的广泛讨论很棒。涵盖 类 和接口的使用等等。我找到的最佳参考。 https://gist.github.com/davejamesmiller/bd857d9b0ac895df7604dd2e63b23afe

Laravel 具有强大的控制反转 (IoC) / 依赖注入 (DI) 容器。不幸的是,官方文档并未涵盖所有可用功能,因此我决定对其进行试验并自己记录下来。以下内容基于 Laravel 5.4.26 - 其他版本可能有所不同。