Dependency Injection (DI) is a design pattern that promotes loose coupling by allowing dependencies to be injected rather than hardcoded within classes. Yii2 provides a built-in DI container to manage dependencies efficiently.
In this tutorial, we will explore how DI works in Yii2, its benefits, and two real-world examples:
Yii2 provides a built-in DI container accessible via Yii::$container. This container allows you to define and resolve dependencies dynamically.
First, create an interface that all payment gateways must implement.
namespace app\services;
interface PaymentGatewayInterface {
public function charge($amount);
}namespace app\services;
class StripePayment implements PaymentGatewayInterface {
public function charge($amount) {
return "Charged $amount via Stripe";
}
}namespace app\services;
class PayPalPayment implements PaymentGatewayInterface {
public function charge($amount) {
return "Charged $amount via PayPal";
}
}Modify config/web.php to set a default payment gateway.
return [
'bootstrap' => [
function () {
Yii::$container->set(PaymentGatewayInterface::class, StripePayment::class);
}
],
];namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\services\PaymentGatewayInterface;
class PaymentController extends Controller {
private $paymentGateway;
public function __construct($id, $module, PaymentGatewayInterface $paymentGateway, $config = []) {
$this->paymentGateway = $paymentGateway;
parent::__construct($id, $module, $config);
}
public function actionCharge() {
$amount = Yii::$app->request->get('amount', 100);
return $this->paymentGateway->charge($amount);
}
}namespace app\services;
interface NotificationServiceInterface {
public function send($recipient, $message);
}namespace app\services;
class EmailNotificationService implements NotificationServiceInterface {
public function send($recipient, $message) {
return "Email sent to {$recipient} with message: '{$message}'";
}
}namespace app\services;
class SmsNotificationService implements NotificationServiceInterface {
public function send($recipient, $message) {
return "SMS sent to {$recipient} with message: '{$message}'";
}
}Modify config/web.php to set a default notification service.
return [
'bootstrap' => [
function () {
Yii::$container->set(NotificationServiceInterface::class, EmailNotificationService::class);
}
],
];Since the service is registered in Yii::$container, it can be retrieved anywhere in the application using Yii::$container->get().
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\services\NotificationServiceInterface;
class NotificationController extends Controller {
public function actionSend() {
$recipient = Yii::$app->request->get('recipient', 'user@example.com');
$message = Yii::$app->request->get('message', 'Hello from Yii2!');
$notificationService = Yii::$container->get(NotificationServiceInterface::class);
$response = $notificationService->send($recipient, $message);
return $this->render('send', ['response' => $response]);
}
}namespace app\models;
use Yii;
use app\services\NotificationServiceInterface;
use yii\db\ActiveRecord;
class User extends ActiveRecord {
public function afterSave($insert, $changedAttributes) {
parent::afterSave($insert, $changedAttributes);
if ($insert) {
$notificationService = Yii::$container->get(NotificationServiceInterface::class);
$notificationService->send($this->email, "Welcome to our platform, {$this->name}!");
}
}
}namespace app\components;
use Yii;
use app\services\NotificationServiceInterface;
class OrderProcessor {
public function processOrder($order) {
Yii::$container->get(NotificationServiceInterface::class)->send($order->user->email, "Your order #{$order->id} has been processed.");
}
}| Approach | Pros | Cons |
|---|---|---|
| Injecting in Controller | - Makes dependencies explicit- Better for Unit Testing | - Requires passing dependency manually |
| Fetching from DI Container | - Can be used anywhere in app- No need to inject into constructor | - Harder to mock for testing |
Using Dependency Injection in Yii2 allows for clean, maintainable, and testable code. Whether you choose to inject dependencies in controllers or resolve them directly from the DI container, Yii2 provides a flexible and efficient way to manage dependencies in your application.
Sign in to join the discussion and post comments.
Sign in