可以用`app :: make('\ App \ User')`创建一个实例,但不能用`new User();`

时间:2018-03-21 00:04:32

标签: php laravel dependency-injection

这是模特:

namespace App;

use L5SimpleFM\FileMakerModels\BaseModel;

class User extends BaseModel
{
    protected $connection = 'filemaker';
    protected $layoutName = 'Web : User';
}

扩展了这个抽象类:

namespace L5SimpleFM\FileMakerModels;
use L5SimpleFM\Contracts\FileMakerInterface;  

abstract class BaseModel
    {

        protected $layoutName;
        protected $connection;

        public function __construct(FileMakerInterface $fm)
        {
            $this->connection = $fm->setLayout($this->layoutName);
        }
        ...
    }

这个抽象类有一个注入接口的实例(?)。现在,在这种情况下,我并不完全理解依赖注入。当我尝试使用new User创建我的用户模型的实例时,它失败,因为它表示它需要__constructor中的参数,因为它扩展了抽象类BaseModel。

我可以使用App::make('\App\User')创建一个实例,也可以在控制器中创建一个实例,如果我创建一个到这个方法的路径,可以得到结果,如下例所示:

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\User;

class UserController extends Controller
{
    protected $user;

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

    public function findUsers()
    {

        $result = $this->user->findAll()->executeCommand();
        $records = $result->getRows();
        return compact('records');
    }
}

和路线:

Route::get('user', 'UserController@findUsers');

访问上述路线时,我得到了所需的输出,但是当我在工匠修补匠中输入new \App\User时,我得到了:

  

TypeError:函数L5SimpleFM \ FileMakerModels \ BaseModel :: __ construct()的参数太少,0传递在C:\ xampp \ htdocs \ FMTest \ vendor \ psy \ psysh \ src \ Psy \ ExecutionLoop \ Loop.php(90 ):eval()'代码在第1行,正好是1预期

但是$x = App::make('\App\User');确实有用,我可以在$x上运行方法。

请帮助我理解这一点。

1 个答案:

答案 0 :(得分:2)

修改

由于OP澄清BaseClass是第三方软件包,现在这是正确答案:

namespace App;

use L5SimpleFM\FileMakerModels\BaseModel;

class User extends BaseModel
{
    protected $connection = 'filemaker';
    protected $layoutName = 'Web : User';

    function __construct () {
        parent::__construct(app(FileMakerInterface::class));
    }
}

Laravel不提供所有地区的DI(依赖注入)。通常,文档会提示或让您知道在哪里可以请求控制器方法或构造函数等签名中的依赖项。 Laravel的模型构造函数不符合DI请求的条件,因为实例化模型和分配数据是一种通过ORM插入数据的方法。

要解决您的问题,请通过全局FileMakerInterface帮助程序请求app(),而不是通过构造函数请求。

namespace L5SimpleFM\FileMakerModels;
use L5SimpleFM\Contracts\FileMakerInterface;  

abstract class BaseModel
{

    protected $layoutName;
    protected $connection;

    public function __construct()
    {
        $this->connection = app(FileMakerInterface::class)->setLayout($this->layoutName);
    }
    // ...
}

请参阅https://laravel.com/docs/5.6/container#resolving