Inject services, unclutter your controllers
Since we just tackled everything route related, the next logical step is to get into Controllers. There are those that would have argued that we should have covered migrations, Models and then Controllers/Routes/Views, and there’s no disagreeing with that statement. Maybe I should write two Laravel article series concurrently. In the routing concept, without getting too far into the weeds, the Controller comes next.
https://www.dinocajic.com/laravel-p55-soft-deleted-models-in-routes/
It’s not that we haven’t covered controllers yet, we just haven’t dug into some of the more infrequently/complicated functionality yet. Most of the concepts that we have already covered in routes translate over to controllers, like dependency injections, so what better place to start than discussing Dependency Injection in Laravel Controllers.
To recap dependency injection in general, take a look at the following articles.
https://www.dinocajic.com/laravel-p48-dependency-injection-concept-high-level-php-concept/
https://www.dinocajic.com/laravel-p49-dependency-injection/
https://www.dinocajic.com/laravel-p50-routing-and-dependency-injection/
An interesting concept to remember is that the Service Container is used to resolve all Laravel controllers. Since it does so, we can type-hint any dependencies that the controller may need through the constructor or through a specific method. You might remember the following dependency injection example.
<?php
namespace App\Http\Controllers;
use App\Services\CapitalizeStringService;
use Illuminate\Http\Request;
class DependencyInjectionTestController extends Controller
{
public function index(Request $request, CapitalizeStringService $capitalizeStringService)
{
$upper = $capitalizeStringService->capitalize( $request->input('name') );
return $upper;
}
public function test()
{
$request = app()->make(Request::class);
$capitalizeStringService = app()->make(CapitalizeStringService::class);
$upper = $capitalizeStringService->capitalize( $request->input('name') );
return $upper;
}
}
In the index
method, we type-hinted the CapitalizeStringService
class. We then used it directly inside of the index
method without having to instantiate the CapitalizeStringService
class. The CapitalizeStringService
class is an extremely basic class. It just capitalizes the string.
<?php
namespace App\Services;
class CapitalizeStringService
{
public function capitalize($string)
{
return strtoupper($string);
}
}
Without even fully discussing it, this is the concept of Dependency Injection in controllers. Let’s create another controller and inject a dependency through our constructor. Since we already have a simple class that we can inject, we’ll use the same CapitalizeStringService
class.
# php artisan make:controller AnotherDependencyInjectionController
INFO Controller [app/Http/Controllers/AnotherDependencyInjectionController.php] created successfully.
#
Next, we need to create our constructor that injects CapitalizeStringService
through type-hinting and another method that consumes it.
<?php
namespace App\Http\Controllers;
use App\Services\CapitalizeStringService;
use Illuminate\Http\Request;
class AnotherDependencyInjectionController extends Controller
{
private CapitalizeStringService $capitalizeStringService;
public function __construct(CapitalizeStringService $capitalizeStringService)
{
$this->capitalizeStringService = $capitalizeStringService;
}
public function index(Request $request, )
{
$upper = $this->capitalizeStringService->capitalize( $request->input('name') );
return $upper;
}
}
Next, we need a route to call it.
use App\Http\Controllers\AnotherDependencyInjectionController;
Route::get('/controller-dependency-injection', [AnotherDependencyInjectionController::class, 'index']);
When we visit our route, http://0.0.0.0/controller-dependency-injection?name=dino
, we should see the following: DINO
.
You may be asking yourself if we can delete the __construct()
and just type-hint the property. The answer to that is no, you need to inject it through the constructor.
Laravel Series
Continue your Laravel Learning.
Route to trashed records with confidence
Laravel – P55: Routes Soft – Deleted Models
In part 55 of our Laravel series, learn how to work with soft-deleted Eloquent models inside routes. Configure bindings to include trashed records, build restore endpoints, and prevent 404 errors when referencing archived data.
Inject services, unclutter your controllers
Laravel – P56: Dependency Injection In Controllers
In part 56 of our Laravel series, deep-dive into leveraging the framework’s service container directly inside controllers. See how constructor and method injection reduce boilerplate, improve testability, and keep your business logic sharply focused.
Secure actions with controller-level middleware
Laravel – P57: Middleware In Controllers
In part 57 of our Laravel series, discover how to register and apply middleware directly within controllers. Learn to secure sensitive actions, share common logic, and override route defaults for concise, maintainable code.