Service Container یا سرویس کانتینر در معماری نرمافزار مسئول ساخت آبجکتها و رفع وابستگیهای آنهاست. این مفهوم را نباید با کانتینر اشتباه گرفت. سرویس کانتینر با Dependency Injection و وارونگی کنترل ارتباط دارد و فقط مختص لاراول نیست، هرچند در لاراول یکی از بخشهای اصلی فریمورک است.
جایگاه آن در لاراول
در لاراول، کنترلر، Job و Listener میتوانند کلاسهای وابسته را از طریق Constructor Injection دریافت کنند. اگر کلاس به Interface وابسته باشد، کانتینر باید بداند کدام پیادهسازی را بسازد.
// app/Providers/AppServiceProvider.php
namespace App\Providers;
use App\Contracts\PaymentGateway;
use App\Services\StripeGateway;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(PaymentGateway::class, StripeGateway::class);
$this->app->singleton(ExchangeRateClient::class, fn () => new ExchangeRateClient());
}
}
Bindingها عموماً در register() سرویس پرووایدر مثل AppServiceProvider نوشته میشوند. boot() برای کارهایی است که پس از ثبت سرویسها اجرا میشوند و محل پیشفرض Binding نیست.
final class CheckoutController
{
public function __construct(private PaymentGateway $gateway) {}
public function charge(Order $order)
{
return $this->gateway->charge($order->total);
}
}
چرخه عمر سرویسها
| روش | رفتار | مثال |
|---|---|---|
bind | نمونه جدید هنگام Resolve | سرویس Stateless |
singleton | نمونه مشترک در طول عمر کانتینر | کلاینت با تنظیمات ثابت |
scoped | نمونه مشترک در یک چرخه درخواست یا Job | Context وابسته به درخواست |
در فریمورکهای دیگر
| پلتفرم | راهکار |
|---|---|
| Symfony | Service Container با Autowiring و پیکربندی services.yaml |
| ASP.NET Core | ثبت سرویس با AddTransient، AddScoped و AddSingleton |
| Python | تزریق دستی یا کتابخانههای Dependency Injector |
| Go | Composition Root دستی یا ابزارهایی مانند Wire و Fx |
// ASP.NET Core - Program.cs
builder.Services.AddScoped<IPaymentGateway, StripeGateway>();
builder.Services.AddSingleton<IClock, SystemClock>();
class CheckoutService:
def __init__(self, gateway):
self.gateway = gateway
service = CheckoutService(gateway=StripeGateway())
نکته طراحی
وقتی هر کلاس خودش کانتینر را برای گرفتن سرویس صدا میزند، خطر Service Locator و وابستگی پنهان وجود دارد. تزریق سازنده معمولاً شفافتر است. راهبرد singleton در کانتینر به معنای اجرای تمام جزئیات دیزاین پترن سینگلتون نیست.
اصطلاحات مرتبط: تزریق وابستگی، وارونگی کنترل، اتصال خودکار وابستگیها، دیزاین پترن سینگلتون، سرویس پرووایدر، فساد، سرویس کانتینر.