Laravel:避免在控制器中创建带有构造函数的模型实例


Laravel: Avoid to create instance of a model with a constructor in the controller

我正在学习Laravel 4的课程,老师进行了代码重构,并在控制器中引入了一个神奇的方法构造函数

class UtentiController extends BaseController {
    protected $utente;
    public function __construct(Utenti $obj) {  
        $this->utente = $obj;
    }
    public function index() {
        $utenti = $this->utente->all();
        return View::make('utenti.index', ["utenti" => $utenti]);
    }
    public function show($username) {
        $utenti = $this->utente->whereusername($username)->first(); //select * from utenti where username = *;
        return View::make('utenti.singolo', ["utenti" => $utenti]);
    }
    public function create() {
        return View::make('utenti.create');
    }

    public function store() {
        if (! $this->utente->Valido( $input = Input::all() ) ) {
            return Redirect::back()->withInput()->withErrors($this->utente->messaggio);
        }
        $this->utente->save();
        return Redirect::route('utenti.index');
    }
}

多亏了这段代码,我不必每次都创建Utenti模型的新实例:

protected $utente;
public function __construct(Utenti $obj) {
    $this->utente = $obj;
}

现在我可以用这个简单的方法访问数据库:

$this->utente->all();

而之前,我不得不这样做:

$utente = new Utente;
$utente::all();

这种技术有名字吗?(这是一种模式吗?)。

我的理解是,每次调用控制器时,它都会自动生成User类(模型)的一个实例,并应用别名(引用)属性$utente

这是正确的吗?

此外,以下是Utenti型号的代码:

class Utenti extends Eloquent {
    public static $regole = [
        "utente" => "required",
        "password" => "required"
    ];
    public $messaggio;
    public $timestamps = false;
    protected $fillable = ['username','password'];
    protected $table = "utenti";
    public function Valido($data) { 
        $validazione = Validator::make($data,static::$regole);
        if ($validazione->passes()) return true;
        $this->messaggio = $validazione->messages();
        return false;
    }
}

这被称为依赖注入或短DI。当创建控制器的新实例时,Laravel会检查构造函数中是否有类型提示的参数(定义了类似__construct(Utenti $obj){的类型的参数)。如果您的控制器有这些参数中的任何一个,则Laravel尝试创建类的实例,并将其注入构造函数中。

这样做的原因是,类(在本例中是您的控制器)的依赖关系变得非常清楚。如果您键入hint接口而不是具体类,则会变得特别有趣。然后,您必须通过绑定告诉Laravel它应该注入接口的哪个实现,但您也可以轻松地交换实现或模拟它进行单元测试。

以下是一些链接,您可以在其中获得更多信息:

  • Laravel docs IoC容器
  • Laravel 5中的方法依赖性注入
  • StackOverflow-什么是控制反转