Laravel,依赖注入和Eloquent

时间:2017-04-28 22:45:52

标签: php laravel dependency-injection

使用laravel的依赖注入系统与CRUD模型等多实例对象的正确/最佳方式是什么?

PHP-land的某些角落目前的时尚说下面的代码是"坏"

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

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

然而 - 注入雄辩的模型似乎有问题

/*...*
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附带任何可以帮助的东西(基础工厂/存储库实现等)

3 个答案:

答案 0 :(得分:1)

感谢LaraChat Slack的一些帮助,我自己想出了这个。

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

考虑此代码示例

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

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

答案 1 :(得分:1)

Laravel DI的广泛讨论很棒。涵盖了类和接口的使用以及更多内容。我找到的最佳参考。 https://gist.github.com/davejamesmiller/bd857d9b0ac895df7604dd2e63b23afe

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

答案 2 :(得分:0)

我有一点玩这个(没有严肃的测试),看起来它是可能的 - 事实上,我更喜欢它这样做,并在未来看它。样品(未经测试)如下:

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

}

在雄辩的立面上找到帮助者,比如查找,很不错,但基本上它们是标准的(...) - > get() - > first()。