4

I'm trying to wrap my head around dependency injection and the IoC container and i'm using my UserController as an example. I'm defining what the UserController depends on in its constructor and then am binding those objects to it using App::bind(). If i'm using the Input::get() facade/method/thing am i not taking advantage of the Request object i just injected into it? Should i be using the following code instead, now that the Request object is injected or doesInput::get() resolve to the same Request instance? I'd like to use the static facades but not if they resolve to un-injected objects.

$this->request->get('email');

Dependency injection

<?php
App::bind('UserController', function() {
    $controller = new UserController(
        new Response,
        App::make('request'),
        App::make('view'),
        App::make('validator'),
        App::make('hash'),
        new User
    );
    return $controller;
});

UserController

<?php
class UserController extends BaseController {

protected $response;
protected $request;
protected $validator;
protected $hasher;
protected $user;
protected $view;

public function __construct(
    Response $response,
    \Illuminate\Http\Request $request,
    \Illuminate\View\Environment $view,
    \Illuminate\Validation\Factory $validator,
    \Illuminate\Hashing\BcryptHasher $hasher,
    User $user
){
    $this->response = $response;
    $this->request = $request;
    $this->view = $view;
    $this->validator = $validator;
    $this->hasher = $hasher;
    $this->user = $user;
}

public function index()
{
    //should i use this?
    $email = Input::get('email');
    //or this?
    $email = $this->request->get('email');

    //should i use this?
    return $this->view->make('users.login');

    //or this?
    return View::make('users.login');
}
David
  • 10,418
  • 17
  • 72
  • 122

1 Answers1

10

If you're worried about a testability thing then you should really only be injecting instances that aren't being routed through a facade, as the facades themselves are testable already (meaning you can mock these in L4). You shouldn't need to inject the response, hasher, view environment, request, etc. By the looks of it you only need to be injecting the $user.

For everything else I'd just stick to using the static facade. Check out the swap and shouldReceive methods on the base Facade class. You can easily swap out the underlying instance with your own mocked object or simply start mocking with, for example, View::shouldReceive().

Hope this helps.

Jason Lewis
  • 18,537
  • 4
  • 61
  • 64
  • 2
    Minus 1 for advocating the following via facades: global state, static calls for coupling (specifically, to the framework), and a service locator for dependency resolution making a liar of your object api. – Jimbo Nov 20 '14 at 11:16
  • 1
    @Jimbo I think what you said underlies my disquiet with Laravel. – Ian Lewis Oct 16 '15 at 08:30