Laravel has a great dependency injection mechanism and in the newest version this mechanism was improved even more. In this article we will review the way dependency injection works, what’s new in the 5th version and why it is amazing.
First of all, let’s see an example of a “classical” constructor dependecy injection.
To inject an instance of a class into a controller (or any other class), you just need to type-hint it in the constructor, like follows:
That’s it! All the “dirty” work is being done by Laravel: it resolves dependencies you type-hinted in the constructor and injects them automatically.
Awesome. But we can make this code even more SOLID and decouple our controller from a specific ClientRepository implementation.
Let’s start with a new interface which describes what methods we expect to be available in the injected repository:
The code above defines four methods which will be available in any class implementing the
ClientRepositoryInterface. As our controller is not intended to know about repository implementation details, we can change the first example to something like this:
Now we do not couple our controller with a particular repository and we can easily replace this dependency with another
ClientRepositoryInterface implementation. But wait, how can Laravel know which particular
ClientRepositoryInterface implementation has to be injected into this controller? Of course, we have to give instructions in a service provider to avoid ambiguity:
Perfect! Now we can change the
ClientRepositoryInterface implementation in the whole project by editing a single line of code in the service provider.
Eco-friendly dependency injection
Ok, now we know that dependency injection in Laravel is awesome and it is a good time to tell you about upcoming improvements in Laravel 5.
Sometimes you can find yourself injecting dependencies which are needed only in a single method of a class. In the age of eco-friendly technologies doing such wasteful things is unacceptable. That’s why in the upcoming version Laravel introduces the method injection!
As you probably suspect, everything you read in the previous section is also valid on a method level:
Considering that we have already created a service provider and a contract, you, of course, can (and probably should) do the following:
Isn’t that great?
But there are some other good news. If you are injecting a dependency into a controller method which accepts parameters from URL, the order of parameters is not important! Laravel uses Reflection to parse and inject dependencies, so the framework exactly knows which parameters come from the URL, and those which should be resolved and injected:
As I have already mentioned, Laravel has an impressive dependency injection functionality but the upcoming version makes it nearly perfect.
Method injection can be useful in many situations such as different validation rules for
update actions, different services needed in different controller actions and class methods, and in many other use-cases.
One of these cases will be reviewed in the upcoming article about validation in Laravel 5, so stay tuned and keep loving the amazing Laravel framework!