Laravel — Automation Using Container Events

It’s been quite a long time I’ve written an article on my blog, last time I’ve written about Laravel Form Validation Using Middleware and it’s about Laravel again. This time I’m going to discuss abour the Service Container (also known as IoC Container). As the title indicates that, this article is about using the event mechanism of the Service Container component that comes out of the box with Laravel framework.

In this case, I’m not going to give an introduction about Laravel framework but a little bit about the Service Container component and in short, it’s responsible for managing the class dependencies which performs dependency injection on run time. In other words, it injects dependent objects into a class automatically when a class needs them. If you are new to Laravel then please follow the link.

Anyways, let’s continue. So, the Service Container component allows us to bind class dependencies so that, when we need a class we may ask the Service Container component to give us an instance of that class and the Service Container component will give us an object instance of that class without any problem even if that class has other dependencies. For example, we may declare a binding like the following:

\App::bind('HelpSpot\API', function ($app) { return new HelpSpot\API($app['HttpClient']); });

In this case, when we need the instance of HelpSpot\API class, we can simply ask for it using the following code:

$api = \App::make('HelpSpot\API');

In this case, the Service Container component will give us the instance of the class and it’ll also inject the dependent HttpClient object into the constructor method of HelpSpot\API class because we’ve told it to do so for use using the App::bind method. Okay, I’m not going to describe how to bind and resolve class dependencies through the Service Container, it was just an intro to for the sake of this topic. If you want to know more about use case of Service Container then please follow this link.

So, the Service Container component fires an event each time it resolves an object and we may listen to this event using the resolving method. For example:

$this->app->resolving(FooBar::class, function (FooBar $fooBar, $app) { // Called when container resolves objects of type "FooBar" });
$this->app->resolving(FooBar::class, function (FooBar $fooBar, $app) { // Called when container resolves objects of type "FooBar" });

So, this way we can listen to resolving action action so when the Service Container will resolve the class we’ll get a chance to do something even before the object is being injected into the called class by the container. Well, that’s the topic that I’m trying to discuss here.

Wait, but that’s not new and it’s already well documented on the Laravel website. Exactly it is but probably it’s not clear enough to you how you can utilize this feature to do some awesome works. For example, think about the Form Request class that Laravel provide us to automatically validate a form submission and redirect back with the errors and submitted inputs on failed validation even without triggering the validation by ourselves. It just happens automatically by only creating a Form Request class and hooking it into our method where we want to trigger the form validation. Isn’t it cool? Exactly it’s, without any doubts.

So, how does this happen, can we implement something similar? Yes, absolutely. This where the Container Event comes in to play. We can hook an automatic method call by registering a resolving callback for any class or abstract type (interface/abstract class) using the resolving event on the Service Container. For example, think you want to check whether a user is authorized to access a certain resource of your application. Well, there are many other ways to do that but for the sake of this article I’m using this approach that I’m going to describe now. So, what I want to be done is something like this:

namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Authorize\Authorize; class UserController extends Controller { public function index(Authorize $authorize) { return User::all(); } }

The code given above is very simple. The index method in the UserController shows a list of users from the database. The index method has a dependency which’ll be automatically injected by the Service Container/IoC component when this index method will be invoked. Now, just like any Form Request class I would like to automatically invoke a method from the Authorize class and want to check the user permission/ability and then either allow the the execution of the method or redirect to somewhere, for example, say home page.

To implement such a mechanism we may create an interface and register that interface into the resolving event of Service Container. So, let’s see that in action, first create an interface and put it inside any folder within the app folder, I’ll use app/contracts in this case, so the interface is as given below:


Originally published at www.laravelfeed.com.