This tutorial will go over how Dependency Injection works in Laravel with examples.
public class DependencyService
{
public function test ()
{
// ...
}
}
class DemoController
{
public function __construct(
protected DependencyService $dependencyService) { }
}
In the above example, DependencyService
can be initiated automatically as an Injected Dependency. because the DependencyService constructor is by default without any additional parameters.
How about if DependencyService
has parameters in the constructor such as
public class DependencyService
{
public function __construct (protected string $clientId){
}
public function test ()
{
// ...
}
}
then additional instructions is needed to instantiate the DependencyService
.
go to the app\Providers\AppServiceProvider.php
file, register a binding to tell Laravel how to instantiate a new object of the DependencyService
.
public function register()
{
$this->app()->bind(DependencyService::class, function() {
return new DependencyService('123456');
}
);
app()
method lets you work with Laravel Service Container directly.
If there are multiple dependency services needed to choose from and wire up during runtime, we need to define interfaces. here is how it looks like
interface IDependency
{
public function dowork ();
}
class DependencyService1 implements IDependency
{
public function __construct (protected string $clientId) { }
public function dowork ()
{
}
}
class DependencyService2 implements IDependency
{
public function __construct (protected string $clientId) { }
public function dowork ()
{
}
}
class DemoController
{
public function __construct (protected IDependency $idependency) { }
public function __invoke (Request $request)
{
$this->idependency->dowork();
}
}
in app\Providers\AppServiceProvider.php
$this->app()->bind(IDependency::class, function () {
if (request()->sometype() === 'dep1') {
return new DependencyService1('123');
}
return new DependencyService2('123');
});
in routes\web.php
Route::post('/demo', DemoController::class);
From the above example, dependency can be initiated based on request payload
Write a Unit Test to test it
php artisan make:test DemoTest
<?php
namespace Tests\Feature ;
use App\Demo\IDependency ;
use App\Demo\DependencyService1 ;
use Mockery ;
use Tests\TestCase ;
class DemoTest extends TestCase
{
public function test_demo_returns_a_successful_response ()
{
// Create a mock
$mock = Mockery::mock(DependencyService1::class)->makePartial();
// Set expectations
$mock->shouldReceive('dowork')->once()->andReturnNull();
// Add this mock to the service container
// to take the service class' place.
app()->instance(IDependency::class, $mock);
// Run endpoint
$this->get('/demo')->assertStatus(200);
}
}
Do you like the article “Dependency Injection in Laravel” ? If you want latest update and find more tips and tricks to build your own business platform, please checkout more articles on https://www.productdeploy.com and https://blog.productdeploy.com