ASP.NET Core / دليل حلول تحريري

معالجة إخفاقات تسجيل الاعتماديات ونطاقاتها

حدّد رسم الاعتماديات الفعلي وحدود ملكية الموارد قبل تغيير أعمار الخدمات أو بناء حاوية أخرى.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى

قاعدة معرفة للقراءة فقط · بلا تعليقات عامة

تعرّف على الأعراض

قد يظهر عند بدء التطبيق أو تنفيذ طلب خطأ يفيد بتعذر حل خدمة، أو تستهلك خدمة ذات نسخة واحدة (singleton) خدمة مرتبطة بنطاق (scoped)، أو يرمي العمل لاحقًا ObjectDisposedException. تتعلق هذه الأعراض بعقود التسجيل وأعمار الخدمات، ولا تعني أن الحل هو جعل جميع الخدمات singleton. قد يكشف نص الاستثناء سلسلة الاعتماديات التي فشل حلها؛ فاحفظه مع تجنب كشف إعدادات سرية.

افهم الأسباب المحتملة

  • قد يكون تسجيل الواجهة وتنفيذها غائبًا أو غير متطابق، أو يحتفظ مالك أطول عمرًا بحالة أقصر عمرًا، أو تستمر مهمة بعد التخلّص من نطاقها. وقد يؤدي استدعاء BuildServiceProvider إضافي أثناء التسجيل إلى إنشاء رسم ملكية آخر. لا يثبت نجاح حل الخدمة مرة واحدة صحة مشاركتها أو سلامتها عند التزامن أو تنظيف مواردها.

1. سجّل النوع المطلوب وعمر الخدمة التي تستهلكه

اقرأ أول استثناء ذي صلة، وحدّد نوع الخدمة المطلوبة والجهة التي تستهلكها، وهل يقع الفشل أثناء بناء مزوّد الخدمات أم حل الاعتمادية أم استخدامها لاحقًا. قارن التسجيل الدقيق الذي يتوقعه المنشئ، سواء تعلق بواجهة أو نوع عام أو تسجيل مسمّى. ابدأ برسم اعتماديات اصطناعي صغير، ولا تفحص تطبيق قائم مهيأ أو تعِد تشغيله لمجرد اختبار تخمين.

2. ارسم حدود المشاركة ومسؤولية التخلّص من الموارد

صنّف النسخ ذات العمر singleton أو scoped أو transient، والنسخ التي ينشئها مصنع، وتلك المنشأة مسبقًا، وفق قواعد الحاوية. حدّد من يملك مسؤولية التخلّص من كل كائن، والمدة التي تستخدمه خلالها كل جهة تستعيره. قد تتلقى خدمة scoped استدعاءات متزامنة حتى داخل طلب واحد. أما الاحتفاظ بـHttpContext أو DbContext داخل singleton أو مهمة خلفية فهو عيب تصميم مستقل عن غياب التسجيل.

3. تحقّق من التسجيل المقصود داخل نطاق معزول

يسجّل البرنامج المكتمل واجهة قارئ اصطناعي ويحلّها داخل نطاق صريح يملك موارده، مع تفعيل فحوص مزوّد الخدمات ذات الصلة. يوضح بذلك رسمًا محليًا صحيحًا ونتيجة مفيدة، لكنه لا يفتح قاعدة بيانات ولا يتحقق من بدء مضيف التطبيق أو تنفيذ المستودع الحقيقي. استخدم هذا النمط من الأدلة لعزل رسم الاعتماديات قبل اقتراح تعديل التطبيق.

csharp حلّ رسم اعتماديات scoped اصطناعي تمت مراجعته
using System;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddScoped<IReportReader, SyntheticReader>();
using var provider = services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true, ValidateOnBuild = true });
using var scope = provider.CreateScope();
int result = scope.ServiceProvider.GetRequiredService<IReportReader>().Read();
Console.WriteLine($"read={result}");

internal interface IReportReader { int Read(); }
internal sealed class SyntheticReader : IReportReader { public int Read() => 7; }
الناتج المتوقع
read=7

يحلّ النطاق الصريح القارئ المسجّل ويعيد القيمة 7؛ ولا يُشغَّل أي مكوّن من الخدمات أو المزوّدات المهيأة في التطبيق.

4. امنح العمل طويل العمر نطاقًا محدودًا أو موردًا ينشئه مصنع

إذا احتاج عامل singleton إلى عمل يستخدم خدمات scoped، فأنشئ نطاقًا صالحًا أو موردًا عبر مصنع لوحدة عمل محدودة، وانتظر اكتمال الجهات التي تستخدمه، ثم تخلّص منه. لا تكتفِ بتحويل DbContext إلى singleton أو حلّها من المزوّد الجذري. استخدم سياقات منفصلة للعمليات المتوازية عندما يتطلب تصميم المزوّد ذلك. وحتى بعد طلب الإلغاء، يجب ملاحظة اكتمال العمل قبل تحرير موارده.

5. أزل الملكية المكررة وحلّ الخدمات الخفي

تجنب بناء مزوّد ثانٍ أثناء التسجيل، أو الاحتفاظ بخدمات transient قابلة للتخلّص إلى أجل غير محدود، أو التخلّص داخل أسلوب من اعتماديات تستعيرها من الحاوية. اجمع التسجيلات عند نقطة تركيب الاعتماديات، واجعل الاعتماديات صريحة. وإذا أنشأ مصنع موردًا، فوثّق من يحرره. قد يبقى الحادث محلولًا جزئيًا فقط إذا أُصلح التسجيل وظل حد المهمة اللاحقة والتخلّص من مواردها غير صحيح.

تحقق من نجاح الإصلاح

يجب أن يطبع البرنامج المحلي المكتمل read=7 وينتهي بنجاح. اختبر تطابق هوية الخدمة داخل النطاق نفسه، واستقلال النسخ بين النطاقات، والتخلّص من الموارد، ورفض رسوم الاعتماديات غير الصالحة، والاستخدام بعد التعليق غير المتزامن، بحسب ما ينطبق على الحالة. ثم تحقّق من تسجيلات التطبيق الفعلية ومسار المضيف أو الطلب داخل إعداد تكامل معزول ومصرّح به. لا يثبت نجاح حاوية صغيرة صحة سلوك EF أو تعيين نقاط النهاية أو جميع أعمار الخدمات في الإنتاج.

امنع تكرار المشكلة

  • احتفظ بمخططات أعمار الخدمات، واعتماديات المنشئات والمعالجات، وفحوص النطاق، واختبارات الملكية. راجع الخدمات الخلفية والمصانع كلما تغيرت الاعتماديات. احرص على اكتمال العمل غير المتزامن قبل التخلّص من موارده، وتجنب اختصارات حلّ الخدمات من الجذر أو من موضع عام. أصلح رسم الاعتماديات المقصود بدل إضعاف الفحوص لكي يبدو بدء التطبيق ناجحًا فقط.

المراجع الرسمية