Basically, instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies into the object externally, and you make it somebody else’s problem.
You make it somebody’s else’s problem to inject the dependencies of your class. In the context of Laravel, this “somebody” is Service Container. In Laravel, Service Container is responsible for injecting the dependencies of your class via the constructor.
Anytime, you ask for a dependency in a class like a controller, the service container is responsible for:
- Automatically detecting the dependencies in constructor
- Constructing the dependencies if needed
- Creating the object by passing the dependencies via the constructor
Let’s take a very simple case.
Suppose, you have a class UserController which requires UserRepository as a constructor dependency.
- The Service Container uses PHP’s ReflectionClass to detect the fact that UserRepository should be resolved first.
- Then, it constructs an instance of UserRepository.
- Then, it constructs the instance of UserController class.
I am baffled by so many Laravel Developers not knowing this simple but powerful technique of how the dependencies are resolved and injected. This is a very powerful technique and it can be used to resolve complex object dependencies.
If for some reason, you don’t want Laravel automatically constructing an object, you can also tell the Laravel Service Container how to construct the object by passing a callback which can be used to create a dependency.
You need to create a Service Provider to register the above service.
Anytime, `My\Service` needs to be resolved, the callback is called which is responsible for returning an object.
Real world Example
Suppose, your application requires Facebook’s PHP SDK to access Facebook’s API and your controller is like this:
Now, you need to tell Service Container how to construct an instance of `Facebook\Facebook`.
Notice, I have called the method “singleton” instead of “bind”. The only difference is that services registered with “singleton” are cached and subsequent calls to resolve the service returns the cached services.
Conclusion
Dependency injection is a powerful technique which you can use in Laravel to simplify the creation of objects. By default, Laravel’s Service Container uses Reflection to automatically detect and resolve dependencies. But, you can specify callbacks which can be called to resolve the services.