Laravel dependency injection

Published at

March 23, 2020

Author

Erlend ter Maat

Tags

Laravel, Dependency injection


I wrote about dependency injection in Drupal before. I also mentioned that other frameworks can make it more easy! At Drupal one still has to write some extra code to make dependency injection work. The creators of Laravel made the system to write cleaner code even more clean.

It is that simple!

Inject services in the constructor

Given an example service:

class ExampleDependency {

}

class ExampleService {

    public function __construct(ExampleDependency $dependency) {

    }

}

$serviceInstance = resolve(ExampleService::class);

At laravel every class can be used as a service without any configuration!

Inject services in member methods

class CurrentUser {

    public $name = 'Bob';

}

class ExampleService {

    public function sayHi(CurrentUser $account) {
        return "Hi {$account->name}!";
    }

}

app()->call([resolve(ExampleService::class), 'sahHi']);

How?

Under the hood Laravel uses reflection to find out what a class needs for constructing. If the class resolve mechanism finds a class definition it tries to resolve it as a service, until all requirements are resolved. It then creates a new instance of the class.

Service container binding

Often you would like to look at services in a more abstract way.

interface SomeContract {

}

class ExampleDependency implements SomeContract {

}

class ExampleService {

     public function __construct(SomeContract $someContract) {

     }

}

To make this resolve one has to specify the implementation of the contract in a service container:

class AppServiceContainer {

    public function register() {
        $app->bind(SomeContract::class, function () {
            return new ExampleDependency;
        }
    }

}

// Resolve by contract would now result in the
// registered implementation of the contract.
resolve(SomeContract::class);

Conclusion

Laravel allows you to use any class as a service without any extra configuration or custom code. Of course your are not required to only instantiate all classes using the service mechanism, but this system does make it easy for you to work with dependency injection, and therefore it encourages you to write clean and maintainable code.