جادوی سیمفونی: تزریق وابستگی – انجمن DEV

تزریق وابستگی ها یک اصل اساسی است که توسط رویکردهای مختلف از جمله SOLID توصیه می شود.
به طور عملی تر، به جای انجام این کار:
namespace App\Services;
class MyService {
private $myDependency;
public function __construct()
{
$this->myDependency = new MyDependency();
}
}
شما می توانید این کار را انجام دهید (PHP 8):
namespace App\Services;
class MyService {
public function __construct(private MyDependency $myDependency)
{}
}
با این حال، ممکن است تعجب کنید که چرا بهتر است و چگونه در پشت صحنه کار می کند.
تزریق و سیم کشی خودکار
در یک پروژه مستقل PHP، شما باید کلاسی ایجاد کنید که دارای a باشد تنها اما مسئولیت بسیار ضروری: خواندن پیکربندی ها و نمونه سازی اشیاء.
به لطف این کلاس، می توانید از میانبری که قبلاً دیدیم استفاده کنید.
در Symfony، معمولاً با رابطها و کانتینرهای داخلی (به عنوان مثال، ContainerBuilder
جزء تزریق وابستگی)، که باعث صرفه جویی قابل توجهی در زمان و تلاش می شود.
خواندن عبارت “کانتینر سرویس” غیر معمول نیست. Symfony به پوشه پیکربندی نگاه می کند تا کانتینرهای خود را بسازد. به همین دلیل باید در فایل های کانفیگ خاصی بنویسید.
Symfony جادوهای زیادی در پشت صحنه انجام می دهد و ویژگی هایی مانند ارائه می دهد سیم کشی خودکار.
با فعال کردن سیمکشی خودکار، به Symfony میگویید که وابستگیها را به طور خودکار در سرویسها تزریق کند:
# config/services.yaml
services:
_defaults:
autowire: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Tests,Kernel.php}'
منبع: Symfony doc – Autowiring
از اعلانهای دستی جلوگیری میکند و کلاسها بهطور خودکار بهعنوان خدمات ثبت میشوند و برای سیمکشی خودکار پیکربندی میشوند.
به این ترتیب، می توانید وابستگی های خود را بارگیری کنید به صورت خودکار و از آنها در کنترلرهای خود استفاده کنید.
چه تاثیری روی اجراها دارد؟
در پشت صحنه، Symfony چندین بهینه سازی را انجام می دهد که ما در اینجا نخواهیم دید، از جمله ذخیره سازی و کامپایل پیشرفته.
به همین دلیل است که “هیچ جریمه ای برای استفاده از سیم کشی خودکار وجود ندارد”، به جز در محیط های توسعه دهنده که احتمالاً هسته چندین بار ظرف را بازسازی می کند.
ظروف آماده برای استفاده
برنامه های ارائه شده توسط Symfony نیازی به زحمت ندارند. کانتینرها تقریباً شامل تمام خدمات مورد نیاز هستند.
آنها فقط باید آنها را به عنوان آرگومان تایپ کنند تا شروع به استفاده از آنها کنند.
به عنوان مثال، اگر به گزارش نیاز دارید:
namespace App\Service;
use Psr\Log\LoggerInterface;
class MyClass
{
public function __construct(
private LoggerInterface $logger,
) {
}
}
منبع: اسناد Symfony – پیکربندی سرویس در یک سرویس
شما حتی اکنون می توانید مشخص کنید که آیا یک سرویس باید با توجه به محیط به لطف ویژگی های PHP 8 ثبت شود یا خیر:
#[When(env: 'dev')]
class MyClass
{
}
بسته شدن
هیچ رویکرد نهایی وجود ندارد، اما تزریق وابستگی برای تعمیر و نگهداری بسیار بهتر از کوپلینگ دستی است.
Symfony فرآیند را ساده می کند و بهینه سازی های عمده را در پشت صحنه اجرا می کند، بنابراین شما با رعایت استانداردها عملاً این ویژگی را به صورت رایگان (از لحاظ اجرا) دریافت می کنید.