SamC

Laravel dependency injection

Recommended Posts

Still not sure whether 'dev talk' means talk about just PW or anything else?! Anyway, been working with Laravel for a bit now but still a bit confused about a certain thing. For example:

namespace App\Http\Controllers;

// Bring Project model into namepsace
use App\Project;

class ProjectsController extends Controller
{
    /**
     * Save new project
     */
    public function store()
    {
        $project = new Project(); // <<<<<< NEW OBJECT
        $project->title = request('title');
        $project->description = request('description');
        $project->save();

        // A GET request by default
        return redirect('/projects');
    }
}

... but I've since found out that you don't need to instantiate a new object in a method, you can type hint like so:

/**
 * Update existing project
 */
public function update(Project $project)
{
    // Update and save
    $project->title = request('title');  // <<<<<< OBJECT IS AVAILABLE LIKE MAGIC
    $project->description = request('description');
    $project->save();

    // A GET request by default
    return redirect('/projects/' . $project->id);
}

What I'm confused with is how type hinting creates a Project object that is then available in the update() method. Isn't type hinting simply saying "this method expects param 1 to be an Object of type Project"? i.e. nothing to do with dependency injection.

Any hints would be awesome, thanks.

Share this post


Link to post
Share on other sites

I'm mostly guessing. I've seen quite a bunch of tutorials using laravel, but never actually used it, so I try:

I'm expecting that laravel uses reflection to know the type hint you put for the parameter and depending on the result do some boilerplate code you could've written on your own to retrieve the project and call the controller action with it.

  • Like 1

Share this post


Link to post
Share on other sites

Ah, ok, thanks guys. I did wonder one other thing, there seems to be numerous ways to achieve something, like, which approach would you use, inject into a method, or into the constructor? Both work in my case here (only showing one method, there are more, but they do not ALL need the Project class, create() for example just returns a view). So would you (the Laracasts showing me how to do this way):

namespace App\Http\Controllers;

use Illuminate\Http\Request;
// Bring Project model into namepsace
use App\Project;

class ProjectsController extends Controller
{
    public function show(Project $project)
    {
        return view('projects.show', compact('project'));
    }
}

...OR (the way shown in @Wanze's link above from Laravel docs):

namespace App\Http\Controllers;

use Illuminate\Http\Request;
// Bring Project model into namepsace
use App\Project;

class ProjectsController extends Controller
{
    protected $project;

    // Inject Project model here instead of on multiple methods
    public function __construct(Project $project)
    {
        $this->project = $project;       
    }

    public function show($id)
    {
        $project = $this->project->findOrFail($id);
        return view('projects.show', compact('project'));
    }
}

Would one way be considered 'better' than the other way? Does it just depend on how many methods actually need the other class? i.e. what's the point of instantiating in the constructor if 3 methods need it, and 3 methods don't. That kind of thing?

Not sure I like compact() either, it's not obvious to me (lack of experience?) what's actually being passed to the view. I know there are other ways.

If you use artisan to set this up automagically:

php artisan make:controller ProjectsController -r -m Project

...it results with the former i.e. no constructor, which seems weird seeing as their docs say:

Quote

In practice, this is how most of your objects should be resolved by the container.

i.e. using a constructor: https://laravel.com/docs/5.7/container#automatic-injection

Share this post


Link to post
Share on other sites

  • Recently Browsing   0 members

    No registered users viewing this page.