繁体   English   中英

Laravel 控制器依赖注入

[英]Laravel Controller Dependency Injection

我正在尝试在 Laravel 中进行依赖注入,以使我的控制器和模型尽可能地纤薄。 目标是拥有存储库来处理归因于某些模型的数据的获取。

为此我试图从文档效仿这里和受欢迎的Laravel样板这里

但我不明白$user来自哪里。

所以看看样板文件,我们有两个文件:

ProfileController 在这里

摘录如下:

use App\Repositories\Frontend\Access\User\UserRepository;
/**
 * Class ProfileController.
 */
class ProfileController extends Controller
{
    /**
     * @var UserRepository
     */
    protected $user;
    /**
     * ProfileController constructor.
     *
     * @param UserRepository $user
     */
    public function __construct(UserRepository $user)
    {
        $this->user = $user;
    }

这看起来很像文档中提到的依赖注入,它是这样的:

class UserController extends Controller {

     /**
         * The user repository instance.
         */
        protected $users;

        /**
         * Create a new controller instance.
         *
         * @param  UserRepository  $users
         * @return void
         */
        public function __construct(UserRepository $users)
        {
            $this->users = $users;
        }

我的问题是我不明白$user来自哪里。

UserRepository 中,没有将 $user 定义为类本身的参数。 代码中没有任何Auth::user()所以我对用户实例来自哪里感到困惑。

在 Laravel 中,依赖注入由Container处理。 我正在简化,但您可以将容器视为对象的来源。 如果有单例,则将其存储在容器中。 否则容器知道如何为您实例化对象。 每当 Laravel 调用一个方法(例如在控制器中)或为您实例化一个对象时,它都会检查构造函数并查找类型提示的依赖项。 如果它看到一个依赖项,它知道如何检索或创建它会这样做并为您传递它。

所以当 Laravel 实例化控制器时,它会查看构造函数

public function __construct(UserRepository $user)
{
    $this->user = $user;
}

容器使用类型提示来查看它需要一个UserRepository以便为您实例化一个新的。 它也递归地执行此操作。 因此,当它创建一个新的UserRepository时,它会查看该构造函数并发现它需要一个RoleRepository因此它也会实例化它。

TLDR:服务容器会检查您的依赖项并为您实例化它们。

欢迎来到 Laravel 的神秘魔法。 这些依赖注入的基本思想是,根据你定义路由和控制器的方式,Laravel 可以执行一些 url 的自动解析、这些 url 中的 id 识别以及对象的数据库获取。

我的问题是我不明白 $user 来自哪里。

您可能应该阅读有关服务容器文档 您还可以使用以下命令更好地了解路由定义如何转换为包含参数的 url:

php artisan route:list

在我的一个项目中,这会导致以下输出:

+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
| Domain | Method    | URI                        | Name               | Action                                          | Middleware   |
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
|        | GET|HEAD  | /                          |                    | Closure                                         | web          |
|        | GET|HEAD  | api/user                   |                    | Closure                                         | api,auth:api |
|        | GET|HEAD  | categories                 | categories.index   | App\Http\Controllers\CategoryController@index   | web          |
|        | POST      | categories                 | categories.store   | App\Http\Controllers\CategoryController@store   | web          |
|        | GET|HEAD  | categories/create          | categories.create  | App\Http\Controllers\CategoryController@create  | web          |
|        | GET|HEAD  | categories/{category}      | categories.show    | App\Http\Controllers\CategoryController@show    | web          |
|        | PUT|PATCH | categories/{category}      | categories.update  | App\Http\Controllers\CategoryController@update  | web          |
|        | DELETE    | categories/{category}      | categories.destroy | App\Http\Controllers\CategoryController@destroy | web          |
|        | GET|HEAD  | categories/{category}/edit | categories.edit    | App\Http\Controllers\CategoryController@edit    | web          |
|        | GET|HEAD  | products                   | products.index     | App\Http\Controllers\ProductController@index    | web          |
|        | POST      | products                   | products.store     | App\Http\Controllers\ProductController@store    | web          |
|        | GET|HEAD  | products/create            | products.create    | App\Http\Controllers\ProductController@create   | web          |
|        | GET|HEAD  | products/{product}         | products.show      | App\Http\Controllers\ProductController@show     | web          |
|        | PUT|PATCH | products/{product}         | products.update    | App\Http\Controllers\ProductController@update   | web          |
|        | DELETE    | products/{product}         | products.destroy   | App\Http\Controllers\ProductController@destroy  | web          |
|        | GET|HEAD  | products/{product}/edit    | products.edit      | App\Http\Controllers\ProductController@edit     | web          |
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+

所有这些路由及其 uri 和参数仅从几个非常简单的路由定义生成。 这是我的路由文件:

$ cat routes/web.php
<?php

Route::get('/', function () {
    return view('master');
});

Route::resource('products', 'ProductController');
Route::resource('categories', 'CategoryController');

如果您查看上面路由输出中的 URI 列表,您将看到在 URI 中命名的参数,例如{category}{product} 这些对应于 Laravel 识别的 URI 中的 ids/keys。 Laravel 足够“聪明”,可以查看我的控制器文件,查看各种函数中的类型提示,并检测到我的函数期望注入依赖项。

例如,类别控制器的show方法如下所示:

public function show(Tree $category)
{
    var_dump($category);
}

我的控制器可能看起来有点不寻常,因为我的类型暗示我想要一个 Tree 类型的对象,但 Laravel 足够聪明,可以识别出我实际上想要一个 Tree 类型的模型,所以它解析出 url 并找到id 并自动获取我的数据库表树中的记录,id 与我的 url 的 {category} 片段匹配,并将其注入我的函数中。

请注意,当我尝试将输入参数命名为 $tree 而不是 $category 时遇到了一些麻烦 其他线程也可能有助于回答您的问题。

最重要的是,Laravel 做了很多“魔法”,希望让您免于手动定义自己的代码和查询以检索所需对象的繁琐。

我正在尝试在Laravel中进行依赖注入,以使我的控制器和模型尽可能的苗条。 目标是拥有存储库来处理归因于某些模型的数据。

为此我试图从文档效仿这里和受欢迎的Laravel样板这里

但是我不知道$user的来源。

因此,查看样板文件,我们有两个文件:

这里ProfileController

摘录如下:

use App\Repositories\Frontend\Access\User\UserRepository;
/**
 * Class ProfileController.
 */
class ProfileController extends Controller
{
    /**
     * @var UserRepository
     */
    protected $user;
    /**
     * ProfileController constructor.
     *
     * @param UserRepository $user
     */
    public function __construct(UserRepository $user)
    {
        $this->user = $user;
    }

这看起来很像文档中提到的依赖项注入,即:

class UserController extends Controller {

     /**
         * The user repository instance.
         */
        protected $users;

        /**
         * Create a new controller instance.
         *
         * @param  UserRepository  $users
         * @return void
         */
        public function __construct(UserRepository $users)
        {
            $this->users = $users;
        }

我的问题是我不知道$user的来源。

UserRepository中,没有$ user定义为类本身的参数。 代码中没有任何Auth::user()所以我对于用户实例的来源感到困惑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM