【问题标题】:Laravel, Dependency Injection, and EloquentLaravel、依赖注入和雄辩
【发布时间】:2017-09-27 03:23:48
【问题描述】:

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

PHP 领域某些角落的当前流行说以下代码是“坏的”

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 提供了任何可以在这里提供帮助的东西(基础工厂/存储库实现等)

【问题讨论】:

    标签: php laravel dependency-injection


    【解决方案1】:

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

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

    雄辩的外观上的 find 助手(例如 find)很不错,但本质上它们是标准的 where(...)->get()->first()。

    【讨论】:

      【解决方案2】:

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

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

      考虑这个代码示例

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

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

      【讨论】:

      • 只是给脸一个名字,这就是路由绑定的全部意义,对吧?
      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-11
        • 2018-10-11
        • 1970-01-01
        • 2015-03-04
        • 2020-07-29
        • 2018-02-20
        • 2014-11-08
        • 1970-01-01
        相关资源
        最近更新 更多