آموزش تزریق وابستگی (Dependency Injection) در لاراول

در توسعه نرم‌افزارهای مدرن، نگهداری و تست‌پذیری کدها اهمیت بالایی دارد. یکی از تکنیک‌های کلیدی برای دستیابی به این اهداف، استفاده از تزریق وابستگی (Dependency Injection) است. در فریمورک لاراول، تزریق وابستگی به شکلی ساده و قدرتمند پیاده‌سازی شده و به توسعه‌دهندگان این امکان را می‌دهد که کلاس‌ها و سرویس‌های خود را بدون سخت‌کدنویسی وابستگی‌ها، مدیریت کنند.
در این مقاله، ابتدا مفهوم تزریق وابستگی را توضیح می‌دهیم، سپس روش‌های مختلف پیاده‌سازی آن در لاراول مانند تزریق از طریق سازنده (Constructor Injection)، تزریق متدی (Method Injection) و تزریق پراپرتی (Property Injection) را بررسی می‌کنیم. همچنین مزایای استفاده از DI در پروژه‌های واقعی و نکاتی برای بهینه‌تر کردن آن را خواهیم آموخت.


Dependency Injection چیست؟

Dependency Injection یک الگو یا تکنیک در برنامه‌نویسی شی‌گرا است که در آن، وابستگی‌های یک کلاس از بیرون کلاس تأمین می‌شود، به جای اینکه خود کلاس آن‌ها را ایجاد کند.

به زبان ساده: به جای اینکه یک کلاس خودش اشیاء مورد نیازش را بسازد، آن‌ها را به آن تحویل می‌دهند.


چرا باید از Dependency Injection استفاده کنیم؟

  • کاهش coupling (وابستگی بین کلاس‌ها)

  • افزایش قابلیت تست (Testing)

  • سادگی تغییرات و نگهداری کد

  • پیاده‌سازی اصول SOLID به خصوص اصل Dependency Inversion


مثال بدون Dependency Injection

فرض کنید یک کلاس داریم که خودش وابستگی‌هایش را می‌سازد:

class OrderService 
{
    protected $paymentGateway;

    public function __construct() {
        $this->paymentGateway = new PaymentGateway();
    }

    public function processOrder($order) {
        $this->paymentGateway->charge($order->amount);
    }
}

مشکل چیست؟

  • اگر بخواهیم PaymentGateway را تغییر بدهیم، باید OrderService را ویرایش کنیم.

  • تست کردن این کلاس سخت‌تر می‌شود چون وابستگی درون آن سخت‌کد شده است.

این دردسر رو شما در پی اچ پی خام دارید البته این هم بگم که با پکیج هم میتونید توی پروژه های پی اچ پی این مشکل حل کنید ولی لاراول یه چیز دیگست.


مثال با Dependency Injection

با تزریق وابستگی، کلاس به جای اینکه خودش PaymentGateway را ایجاد کند، آن را از بیرون دریافت می‌کند:

class OrderService 
{
    protected $paymentGateway;

    public function __construct(PaymentGateway $paymentGateway) 
    {
        $this->paymentGateway = $paymentGateway;
    }

    public function processOrder($order) 
    {
        $this->paymentGateway->charge($order->amount);
    }
}

حالا OrderService دیگر خودش چیزی نمی‌سازد. فقط از چیزی که به آن داده شده استفاده می‌کند.


نقش Service Container در لاراول

سرویس کانتینر (Service Container) در لاراول یک ابزار قدرتمند برای مدیریت وابستگی‌ها است. وقتی لاراول می‌بیند که کلاسی در سازنده خود وابستگی‌ای دارد، به طور خودکار نمونه مناسب را از Service Container پیدا کرده و تزریق می‌کند.

مثلاً، اگر در یک کنترلر لاراولی بنویسید:

class OrderController extends Controller
{
    protected $orderService;

    public function __construct(OrderService $orderService)
    {
        $this->orderService = $orderService;
    }

    public function store(Request $request)
    {
        $this->orderService->processOrder($request->order);
    }
}

لاراول به طور خودکار OrderService را تولید و تزریق می‌کند، و اگر OrderService هم به PaymentGateway نیاز داشته باشد، آن را هم تزریق می‌کند!


انواع روش‌های تزریق وابستگی در لاراول

1. Constructor Injection (تزریق از طریق سازنده)

رایج‌ترین روش است که وابستگی‌ها از طریق سازنده (constructor) دریافت می‌شوند، مثال:

public function __construct(ReportService $reportService)
{
    $this->reportService = $reportService;
}

2. Method Injection (تزریق از طریق متد)

در این روش، لاراول پارامترهای متد را نیز می‌تواند به طور خودکار فراهم کند، مثال:

public function generate(ReportService $reportService)
{
    $reportService->generateReport();
}

3. Setter Injection (تزریق از طریق setter)

این روش به صورت مستقیم در لاراول رایج نیست، ولی در الگوهای دیگر مورد استفاده قرار می‌گیرد.


چگونه وابستگی‌های خاص را تعریف کنیم؟

می‌توانیم مشخص کنیم که لاراول چگونه باید یک وابستگی خاص را مدیریت کند. مثلا اگر چند نسخه از یک کلاس داشته باشیم:

use IlluminateSupportFacadesApp;

App::bind(PaymentGateway::class, StripePaymentGateway::class);

با این کار، هر وقت لاراول PaymentGateway خواست، یک نمونه از StripePaymentGateway می‌سازد.

یا به صورت Singleton:

App::singleton(PaymentGateway::class, StripePaymentGateway::class);


نتیجه‌گیری نهایی

Dependency Injection یکی از اصول اساسی توسعه‌ی نرم‌افزار تمیز و قابل نگهداری است. لاراول با ارائه‌ی یک Service Container قوی، کار با DI را بسیار ساده کرده است. با فهم این مفهوم، می‌توانید کدهای تمیزتر، انعطاف‌پذیرتر و حرفه‌ای‌تری در پروژه‌های لاراولی خود بنویسید.

0 🔥
0 🎉
0 😮
1 👍
0 💜
0 👏
میلاد خسروی
نویسنده کد نیوز

برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁