تكرار السؤال: …
الإجابة المختصرة
تحدث عندما تُحقن خدمة ذات نطاق أقصر (مثل Scoped) داخل خدمة ذات نطاق أطول (مثل Singleton)، مما يحبس النسخة الـ Scoped في الذاكرة للأبد ويمنع تنظيفها.
الشرح
إذا قمت بحقن DbContext (وهو Scoped) داخل فئة CacheService (وهي Singleton)، سيظل نفس كائن الـ DbContext حياً طوال عمر التطبيق ولن يتم استدعاء Dispose عليه مطلقاً. هذا يؤدي لتضخم الذاكرة (Memory Leak) ومحاولة استخدام نفس الاتصال عبر خيوط متزامنة مما يرمي أخطاء Concurrency. توفر .NET خيار ValidateScopes الذي يرمي استثناء فورياً عند الإقلاع في بيئة Development إذا وجد هذه التبعية.
مثال بالكود
// مفعل تلقائياً في Development:
builder.Host.UseDefaultServiceProvider(options => {
options.ValidateScopes = true;
options.ValidateOnBuild = true;
});أخطاء شائعة
- تعطيل ValidateScopes في بيئة التطوير لتجاوز الخطأ بدلاً من إصلاح التبعيات.
أسئلة متابعة
- كيف تنفذ المهام الخلفية المستمرة باستخدام فئة BackgroundService وما مخاطر حقن الخدمات الـ Scoped بداخلها؟
- ما الفرق الجوهري بين فترات حياة الخدمات (Lifetimes): Transient و Scoped و Singleton في .NET؟