PHP Dependency Injection with Laravel 5

Dependency Injection in PHP with Laravel 5

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.

Constructor injection

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:

Conclusion

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 create and 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!

  • http://www.sinaneldem.com.tr Sinan Eldem

    Error:

    Class AppRepositoriesClientRepository does not exist

    • http://blog.armen.im/ Armen Markossyan

      Thank you for the comment. ClientRepository is just an example and I don’t provide a particular implementation of it in this article. You can replace this class with any other class / interface you want to inject into a method.