Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel : Dependency injection vs Facades?

What, I had been doing previously was to inject only MY MODELS using the constructor and use Facades for the Laravel's provided classes i.e. Session, Auth, Validator etc, for example. Will it be a good idea if I inject each and every class (either mine or Laravel's) through construct and use it by $this->.. syntax or should I inject my own classes using constructor and use Facades for anything provided by Laravel?

To be more specific, here is what my controllers normally look like:

class MyController extends BaseController 
{
    public function __construct( User $user, Bookmark $bookmark ) {
        $this->user = $user;
        $this->bookmark = $bookmark
    }

    public function foobar ( ) {
        $user_id = Input::get('bar');
        ...
        Session::get('someInfo');
        ...
        return Redirect::to('/');
    }
    ...
}

Should I structure my methods like controller like following, instead?

class MyController extends BaseController 
{
    public function __construct( User $user, Bookmark $bookmark, Input $input, Session $session, Redirect $redirect ) {
        $this->user = $user;
        $this->bookmark = $bookmark
        $this->input = $input;
        $this->session = $session;
        $this->redirect = $redirect;
    }

    public function foobar ( ) {
        $user_id = $this->input->get('bar');
        ...
        $this->session->get('someInfo');
        ...
        return $this->redirect->to('/');
    }
    ...
}
like image 431
Kamran Ahmed Avatar asked Nov 22 '14 18:11

Kamran Ahmed


Video Answer


1 Answers

Laravel now supports the same Dependency-Injection functionality for route-related methods of classes (not just constructors), such as controllers and middleware.

You could prevent unnecessary injections by only injecting to methods where the dependency is unique, perhaps leaving more common dependencies in the constructor:

class MyController extends BaseController 
{
    public function __construct( Input $input, Session $session, Redirect $redirect ) {
        $this->input = $input;
        $this->session = $session;
        $this->redirect = $redirect;
    }

    public function foobar ( User $user, Bookmark $bookmark ) {
        $user_id = $this->input->get('bar');
        ...
        $this->session->get('someInfo');
        ...
        return $this->redirect->to('/');
    }
    ...
}

Conclusion

As for whether you should do it this way, that's up to you, but consider to:

  • First, use Dependency-Injection vs Facade (which also enables IDE auto-completion).
  • Then, wherever dependency is unique (and not required by most routes), use per-method injection vs constructor.
  • Because making all unique dependencies appear in method definition is easier to unit-test (and seems cleaner to me).
like image 66
tjbp Avatar answered Sep 22 '22 17:09

tjbp