Leadسختی 5 از ۵· در 33٪ مصاحبههای این حوزه پرسیده شده
چرا Service Locator یک Anti-Pattern است؟
☆نشان کردنپاسخ کوتاه
چون وابستگیهای واقعی کلاس را پنهان میکند؛ امضای سازنده دیگر نمیگوید کلاس به چه چیزهایی نیاز دارد و خطاها به زمان اجرا موکول میشوند.
پاسخ کامل
در Service Locator، کلاس یک Container را میگیرد و هر وقت لازم داشت از آن سرویس میخواهد. مشکل اینجاست:
- وابستگیهای پنهان: با نگاه به سازنده نمیفهمید کلاس به چه چیزی نیاز دارد.
- شکست در زمان اجرا: فراموشی یک ثبت، بهجای خطای Compile یا خطای startup، وسط یک درخواست کاربر ظاهر میشود.
- تست دشوار: برای تست باید کل Container را بسازید، نه فقط چند Fake.
استثنای مشروع: Factoryها و نقاط ورودی فریمورک (مثل IServiceScopeFactory در یک
Background Service) که ذاتاً باید در زمان اجرا Scope بسازند.
مثال کد
// ❌ Service Locator
public class OrderService
{
private readonly IServiceProvider _provider;
public OrderService(IServiceProvider provider) => _provider = provider;
public void Process()
{
var repo = _provider.GetRequiredService<IOrderRepository>();
}
}
// ✅ وابستگی صریح
public class OrderService
{
private readonly IOrderRepository _repository;
public OrderService(IOrderRepository repository) => _repository = repository;
}
نکته مهم
اگر سازنده یک کلاس بیش از حد شلوغ شده، راهحل پناهبردن به Service Locator نیست؛ نشانه این است که کلاس مسئولیتهای زیادی دارد و باید شکسته شود.
اشتباه رایج
❌ توجیه Service Locator با «سازندهام خیلی پارامتر داشت» — این مشکل طراحی است، نه مشکل DI.
