All you need to know about Laravel Service Container
Laravel Service Container
This is how we will learn about the Laravel Service Container: we'll cover the necessary terminology and concepts, then examine the code to gain a complete understanding.
Concepts:-
Service container
Dependency injection
Registering dependency
Resolving dependency
What is a Service container?
Simple Answer:
Imagine having a magical box called the "Magic Box" that gives you anything you need. Instead of going to different shops, you ask the box for what you want, and it gives it to you. Service Container is like a smart helper for your web app, storing and managing everything it might need.
Technical Answer:
The service container is a powerful tool for managing class dependencies and performing dependency injection. Its sole responsibility is to manage the dependencies in your laravel project.
What is dependency injection?
Dependency injection is a design pattern in which components or services are externally provided to a class. It is typically achieved by providing the required dependencies to a class through constructor parameters, method arguments, or setter methods.
What is Registering dependency?
Registering dependencies in Laravel involves binding abstractions (interfaces or abstract classes) to their concrete implementations within the service container. This enables the framework to automatically resolve and inject the correct implementations when needed throughout the application, simplifying the process of managing and using dependencies.
What is Resolving dependency?
Resolving dependencies in Laravel is obtaining instances of registered classes from the service container. The framework automatically analyzes the required dependencies and fetches their concrete implementations from the container. This process ensures that the correct implementations are readily available for use in the application.
Ways to Register Dependencies
Simple Bindings
Binding A Singleton
Binding Interfaces To Implementations
Dependencies are registered in the ServiceProvider register method.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// here we will register the dependencies
}
}
Simple Bindings
The Transistor class is registered in the service container via the bind
method. Each time this dependency is resolved, a new instance of the class is provided:
use App\Services\Transistor;
use App\Services\PodcastParser;
$this->app->bind(Transistor::class, function ($app) {
return new Transistor($app->make(PodcastParser::class));
});
Binding A Singleton
The singleton
method binds a class or interface into the container that should only be resolved once. Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container:
use App\Services\Transistor;
use App\Services\PodcastParser;
$this->app->singleton(Transistor::class, function ($app) {
return new Transistor($app->make(PodcastParser::class));
});
Binding Interfaces To Implementations
A compelling feature of the service container is its ability to bind an interface to a given implementation. For example, let's assume we have an EventPusher
interface and a RedisEventPusher
implementation. Once we have coded our RedisEventPusher
implementation of this interface, we can register it with the service container like so:
use App\Contracts\EventPusher;
use App\Services\RedisEventPusher;
$this->app->bind(EventPusher::class, RedisEventPusher::class);
meaning whenever the EventPusher
resolved from the container the RedisEventPusher
class implementation will be used.
Ways to Resolve Dependencies
Automatic injection
Property Injection
Automatic injection
// PostController.php:
public function store(StorePostRequest $request) {
Post::create($request->validated());
// ...
}
See that StorePostRequest
as a type-hint in the method? It's a typical Form Request class. Notice that we don't initialize the instance of that class. Laravel does this for us if we type-hint the class.
In other words, we don't need to do this manually inside the method:
$request = new StoreUserRequest();
So this is done by Service Container; it "resolves" the instance of that class and auto-creates the object for us using the PHP Reflection Apis. Another example is through the constructor.
<?php
namespace App\Http\Controllers;
use App\Repositories\PostRepository;
use App\Models\Post;
class PostController extends Controller
{
/**
* Create a new controller instance.
*/
public function __construct(
protected PostRepository $posts,
) {}
/**
* Show the post with the given ID.
*/
public function show(string $id): Post
{
return $this->posts->findOrFail($id);
}
}
Property Injection
In property injection, dependencies are directly assigned to class properties, allowing them to be accessed throughout the class.
Suppose we have an interface ShippingMethod
and two concrete implementations StandardShipping
and ExpressShipping
.
interface ShippingMethod {
public function calculateCost($weight);
}
class StandardShipping implements ShippingMethod {
public function calculateCost($weight) {
// Logic to calculate standard shipping cost based on weight
return $weight * 5;
}
}
class ExpressShipping implements ShippingMethod {
public function calculateCost($weight) {
// Logic to calculate express shipping cost based on weight
return $weight * 10;
}
}
Now, let's create a class OrderProcessor
that uses property injection to handle shipping:
class OrderProcessor {
protected $shippingMethod;
public function setShippingMethod(ShippingMethod $method) {
$this->shippingMethod = $method;
}
public function processOrder($weight) {
$shippingCost = $this->shippingMethod->calculateCost($weight);
// Logic to process the order and calculate the total cost
$totalCost = $shippingCost + /* additional costs */;
return $totalCost;
}
}
By using shippingMethod
property injection, Laravel automatically assigns the appropriate implementation based on the service container's binding. This makes the OrderProcessor
class more flexible and allows for easy switching between shipping methods without modifying the core logic.
Check out the complete documentation for the service container on Laravel official documentation.
https://laravel.com/docs/10.x/container
Want to hire me
- - - - - - -
Email: umairraza@skiff.com