Dependency injection through constructor or function parameter
Hi developers,
I was wondering what the difference is between injecting a (service) class through the constructor of a class and injecting a class as a function parameter. I've tested both approaches, and they both work exactly the same. Why should you inject it through the constructor? What is the purpose of this over injecting it as a function parameter, since they do the same?
I've got an example below. I did not bind anything to the service container manually.
PostService.php
<?php
namespace App\Services;
use App\Models\Post;
class PostService
{
/**
* Convert the post to PDF.
*
* @param Post $post
* @return string
*/
public function convertToPdf(Post $post): string
{
return 'PDF';
}
}
PostController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use App\Services\PostService;
class PostController extends Controller
{
private PostService $postService;
public function __construct(PostService $postService)
{
$this->postService = $postService;
}
/**
* This is through dependency injection in the controller's parameter.
*
* @param Post $retrospective
* @param PostService $postService
* @return string
*/
public function throughConstructor(Post $retrospective, PostService $postService): string
{
return $postService->convertToPdf($retrospective->id);
}
/**
* This is through dependency injection through the constructor.
*
* @param Post $retrospective
* @return string
*/
public function throughFunctionParameter(Post $retrospective): string
{
return $this->postService->convertToPdf($retrospective->id);
}
}
If you need the class available in all of your methods on the controller you can use the constructor. Otherwise it does not make any difference. Personally I prefer to just inject it each method where I need it (I rarely need the same in all methods)
For classes there you call the methods yourself, it can make sense to inject into the constructor as laravel can do that automatically.
So, if I have 6 methods where 2 methods use a function from the service class, is it a no-go to inject in through the constructor and should I rather inject it in the two methods? Or is it still fine to do so?
@LarsWolters I would personally inject it in those two methods. It will make it much more clear that the specific class is used by the specific method. Also when using route model binding, you would add it to the method directly, meaning that your bindings would be spread between methods and the constructor