Dependency Injection in Laravel

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

Share This

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*
*